local extension = Package("joy_qyhc")
extension.extensionName = "joy"

Fk:loadTranslationTable{
  ["joy_qyhc"] = "欢乐-限定",
}

local U = require "packages/utility/utility"


local zhangxuan = General(extension, "joy__zhangxuan", "wu", 4, 4, General.Female)
local tongli = fk.CreateTriggerSkill{
  name = "joy__tongli",
  anim_type = "offensive",
  events = {fk.TargetSpecified},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and player.phase == Player.Play and data.firstTarget and
    data.extra_data and data.extra_data.tongli_target and
    not table.contains(data.card.skillNames, self.name) and player:getMark("@joy__tongli-phase") > 0 and
    data.card.type ~= Card.TypeEquip and data.card.sub_type ~= Card.SubtypeDelayedTrick and
    not (table.contains({"peach", "analeptic"}, data.card.trueName) and
    table.find(player.room.alive_players, function(p) return p.dying end)) then
      local suits = {}
      for _, id in ipairs(player.player_cards[Player.Hand]) do
        table.insertIfNeed(suits, Fk:getCardById(id).suit)
      end
      return #suits == player:getMark("@joy__tongli-phase")
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if player.general == "joy__zhangxuan" then
      player.general = "joy_skin__zhangxuan"
      player.room:broadcastProperty(player, "general")
      player.room:delay(500)
    end
    data.extra_data = data.extra_data or {}
    data.extra_data.tongli = {
      from = player.id,
      tos = data.extra_data.tongli_target,
      times = player:getMark("@joy__tongli-phase")
    }
  end,

  refresh_events = {fk.PreCardUse},
  can_refresh = function(self, event, target, player, data)
    return player == target and player:hasSkill(self, true) and player.phase == Player.Play and
    not table.contains(data.card.skillNames, self.name)
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    room:addPlayerMark(player, "@joy__tongli-phase", 1)
    if type(data.tos) == "table" then
      data.extra_data = data.extra_data or {}
      data.extra_data.tongli_target = table.simpleClone(data.tos)
    end
  end,
}
local parseTongliUseStruct = function (player, name, targetGroup)
  local card = Fk:cloneCard(name)
  card.skillName = "joy__tongli"
  if player:prohibitUse(card) then return nil end
  local room = player.room
  local all_tos = {}
  for _, tos in ipairs(targetGroup) do
    local passed_target = {}
    for _, to in ipairs(tos) do
      local target = room:getPlayerById(to)
      if target.dead then return nil end
      if #passed_target == 0 and player:isProhibited(target, card) then return nil end
      if not card.skill:modTargetFilter(to, passed_target, player.id, card, false) then return nil end
      table.insert(passed_target, to)
      table.insert(all_tos, {to})
    end
  end
  return {
    from = player.id,
    tos = (card.multiple_targets and card.skill:getMinTargetNum() == 0) and {} or all_tos,
    card = card,
    extraUse = true
  }
end
local tongli_delay = fk.CreateTriggerSkill{
  name = "#joy__tongli_delay",
  events = {fk.CardUseFinished},
  anim_type = "offensive",
  can_trigger = function(self, event, target, player, data)
    if data.extra_data and data.extra_data.tongli and not player.dead then
      local dat = table.simpleClone(data.extra_data.tongli)
      if dat.from == player.id then
        local use = parseTongliUseStruct(player, data.card.name, dat.tos)
        if use then
          self.cost_data = use
          return true
        end
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local dat = table.simpleClone(data.extra_data.tongli)
    local use = table.simpleClone(self.cost_data)
    local room = player.room
    player:broadcastSkillInvoke("joy__tongli")
    for _ = 1, dat.times, 1 do
      room:useCard(use)
      if player.dead then break end
    end
    if player.general == "joy_skin__zhangxuan" then
      room:notifySkillInvoked(player,self.name,"drawcard")
      player.general = "joy__zhangxuan"
      room:broadcastProperty(player, "general")
    end
  end,
}
local joy__shezang = fk.CreateTriggerSkill{
  name = "joy__shezang",
  anim_type = "drawcard",
  events = {fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and (target == player or player == player.room.current) and
      player:usedSkillTimes(self.name, Player.HistoryTurn) == 0
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local suits = {1, 2, 3, 4}
    local cards = {}
    local pile = table.simpleClone(room.draw_pile)
    while #pile > 0 and #cards < 4 do
      local id = table.remove(pile, math.random(#pile))
      if table.removeOne(suits, Fk:getCardById(id).suit) then
        table.insert(cards, id)
      end
    end
    if #cards > 0 then
      room:moveCards({
        ids = cards,
        to = player.id,
        toArea = Card.PlayerHand,
        moveReason = fk.ReasonPrey,
        proposer = player.id,
        skillName = self.name,
        moveVisible = true
      })
    end
  end,
}
tongli:addRelatedSkill(tongli_delay)
zhangxuan:addSkill(tongli)
zhangxuan:addSkill(joy__shezang)
Fk:loadTranslationTable{
  ["joy__zhangxuan"] = "张嫙",
  ["joy__tongli"] = "同礼",
  [":joy__tongli"] = "当你于出牌阶段内使用基本牌或普通锦囊牌指定目标后，若你手牌中的花色数等于你此阶段已使用牌的张数，你可令此牌效果额外执行X次（X为你手牌中的花色数）。",
  ["joy__shezang"] = "奢葬",
  [":joy__shezang"] = "每回合限一次，当你或你回合内有角色进入濒死状态时，你可以从牌堆获得不同花色的牌各一张。",
  ["@joy__tongli-phase"] = "同礼",
  ["#joy__tongli_delay"] = "同礼",
}







local caoying = General(extension, "joy__caoying", "wei", 4, 4, General.Female)
local lingren = fk.CreateTriggerSkill{
  name = "joy__lingren",
  anim_type = "offensive",
  events = {fk.TargetSpecified},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Play and data.firstTarget and
    data.card.is_damage_card and player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  on_cost = function(self, event, target, player, data)
    local to = player.room:askForChoosePlayers(player, AimGroup:getAllTargets(data.tos), 1, 1, "#joy__lingren-choose", self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    local choices = {"joy__lingren_basic", "joy__lingren_trick", "joy__lingren_equip"}
    local yes = room:askForChoices(player, choices, 0, 3, self.name, "#joy__lingren-choice::" .. self.cost_data, false)
    for _, value in ipairs(yes) do
      table.removeOne(choices, value)
    end
    local right = 0
    for _, id in ipairs(to.player_cards[Player.Hand]) do
      local str = "joy__lingren_"..Fk:getCardById(id):getTypeString()
      if table.contains(yes, str) then
        right = right + 1
        table.removeOne(yes, str)
      else
        table.removeOne(choices, str)
      end
    end
    right = right + #choices
    room:sendLog{
      type = "#joy__lingren_result",
      from = player.id,
      arg = tostring(right),
    }
    if right > 0 then
      data.extra_data = data.extra_data or {}
      data.extra_data.lingren = data.extra_data.lingren or {}
      table.insert(data.extra_data.lingren, self.cost_data)
    end
    if right > 1 then
      player:drawCards(2, self.name)
    end
    if right > 2 then
      local skills = {}
      if not player:hasSkill("ex__jianxiong", true) then
        table.insert(skills, "ex__jianxiong")
      end
      if not player:hasSkill("joy__xingshang", true) then
        table.insert(skills, "joy__xingshang")
      end
      room:setPlayerMark(player, self.name, skills)
      room:handleAddLoseSkills(player, table.concat(skills, "|"), nil, true, false)
    end
  end,
}
local lingren_delay = fk.CreateTriggerSkill {
  name = "#joy__lingren_delay",
  mute = true,
  events = {fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    if player.dead or data.card == nil or target ~= player then return false end
    local room = player.room
    local card_event = room.logic:getCurrentEvent():findParent(GameEvent.UseCard)
    if not card_event then return false end
    local use = card_event.data[1]
    return use.extra_data and use.extra_data.lingren and table.contains(use.extra_data.lingren, player.id)
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    data.damage = data.damage + 1
  end,
  
  refresh_events = {fk.TurnStart},
  can_refresh = function(self, event, target, player, data)
    return target == player and player:getMark("joy__lingren") ~= 0
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local skills = player:getMark("joy__lingren")
    room:setPlayerMark(player, "joy__lingren", 0)
    room:handleAddLoseSkills(player, "-"..table.concat(skills, "|-"), nil, true, false)
  end,
}
local fujian = fk.CreateTriggerSkill {
  name = "joy__fujian",
  anim_type = "control",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Finish and
      not table.find(player.room.alive_players, function(p) return p:isKongcheng() end)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local targets = room:getOtherPlayers(player, false)
    local to = table.random(targets)
    room:doIndicate(player.id, {to.id})
    U.viewCards(player, table.random(to.player_cards[Player.Hand], 1), self.name)
  end,
}
lingren:addRelatedSkill(lingren_delay)
caoying:addSkill(lingren)
caoying:addSkill(fujian)
caoying:addRelatedSkill("ex__jianxiong")
caoying:addRelatedSkill("joy__xingshang")
Fk:loadTranslationTable{
  ["joy__caoying"] = "曹婴",
  ["#joy__caoying"] = "龙城凤鸣",

  ["joy__lingren"] = "凌人",
  [":joy__lingren"] = "出牌阶段限一次，当你使用【杀】或伤害类锦囊牌指定目标后，你可以猜测其中一名目标角色的手牌区中是否有基本牌、锦囊牌或装备牌。"..
  "若你猜对：至少一项，此牌对其造成的伤害+1；至少两项，你摸两张牌；三项，你获得技能〖奸雄〗和〖行殇〗直到你的下个回合开始。",
  ["joy__fujian"] = "伏间",
  [":joy__fujian"] = "锁定技，结束阶段，你随机观看一名其他角色的一张手牌）。",
  ["#joy__lingren-choose"] = "凌人：你可以猜测其中一名目标角色的手牌中是否有基本牌、锦囊牌或装备牌",
  ["#joy__lingren-choice"] = "凌人：猜测%dest的手牌中是否有基本牌、锦囊牌或装备牌",
  ["joy__lingren_basic"] = "有基本牌",
  ["joy__lingren_trick"] = "有锦囊牌",
  ["joy__lingren_equip"] = "有装备牌",
  ["#joy__lingren_result"] = "%from 猜对了 %arg 项",
  ["joy__lingren_delay"] = "凌人",
}

local baosanniang = General(extension, "joy__baosanniang", "shu", 3, 3, General.Female)
local joy__wuniang = fk.CreateTriggerSkill{
  name = "joy__wuniang",
  anim_type = "control",
  events = {fk.CardUsing, fk.CardResponding},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card.trueName == "slash" and
      not table.every(player.room:getOtherPlayers(player), function(p) return p:isNude() end)
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local prompt = "#joy__wuniang1-choose"
    if player:usedSkillTimes("joy__xushen", Player.HistoryGame) > 0 and
      table.find(room.alive_players, function(p) return string.find(p.general, "guansuo") end) then
      prompt = "#joy__wuniang2-choose"
    end
    local to = room:askForChoosePlayers(player, table.map(table.filter(room:getOtherPlayers(player), function(p)
      return not p:isNude() end), Util.IdMapper), 1, 1, prompt, self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, player, target, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    local id = room:askForCardChosen(player, to, "he", self.name)
    room:obtainCard(player.id, id, false, fk.ReasonPrey)
    if not to.dead then
      to:drawCards(1, self.name)
    end
    if player:usedSkillTimes("joy__xushen", Player.HistoryGame) > 0 then
      for _, p in ipairs(room.alive_players) do
        if string.find(p.general, "guansuo") and not p.dead then
          p:drawCards(1, self.name)
        end
      end
    end
  end,
}
local joy__xushen = fk.CreateTriggerSkill{
  name = "joy__xushen",
  anim_type = "defensive",
  frequency = Skill.Limited,
  events = {fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.dying and player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:recover({
      who = player,
      num = 1,
      recoverBy = player,
      skillName = self.name
    })
    room:handleAddLoseSkills(player, "ty__zhennan", nil, true, false)
    if player.dead or table.find(room.alive_players, function(p) return string.find(p.general, "guansuo") end) then return end
    local targets = table.map(room:getOtherPlayers(player), Util.IdMapper)
    local to = room:askForChoosePlayers(player, targets, 1, 1, "#joy__xushen-choose", self.name, true)
    if #to > 0 then
      to = room:getPlayerById(to[1])
      if room:askForSkillInvoke(to, self.name, nil, "#joy__xushen-invoke") then
        if player.general == "joy__baosanniang" then 
          room:notifySkillInvoked(player, "joy__xushen","drawcard")
          room:changeHero(player,"joy_skin__baosanniang",false,false,true,false)
          room:notifySkillInvoked(to, "joy__xushen","drawcard")
            room:changeHero(to, "joy_skin__guansuo", false, false, true)
            if not to.dead then
        to:drawCards(3, self.name)
      end
        elseif player.deputyGeneral == "joy__baosanniang" then
          room:notifySkillInvoked(player, "joy__xushen","drawcard")
          room:changeHero(player,"joy_skin__baosanniang",false,true,true,false)
          room:notifySkillInvoked(to, "joy__xushen","drawcard")
        room:changeHero(to, "joy_skin__guansuo", false, false, true)
        if not to.dead then
        to:drawCards(3, self.name)
      end
        else
        room:changeHero(to, "joy__guansuo", false, false, true)
        if not to.dead then
        to:drawCards(3, self.name)
      end
        end
      end
      
    end
  end,
}

baosanniang:addSkill(joy__wuniang)
baosanniang:addSkill(joy__xushen)
baosanniang:addRelatedSkill("ty__zhennan")
Fk:loadTranslationTable{
  ["joy__baosanniang"] = "鲍三娘",
  ["#joy__baosanniang"] = "南中武娘",

  ["joy__wuniang"] = "武娘",
  [":joy__wuniang"] = "当你使用或打出【杀】时，你可以获得一名其他角色的一张牌，若如此做，其摸一张牌。若你已发动〖许身〗，则关索也摸一张牌。",
  ["joy__xushen"] = "许身",
  [":joy__xushen"] = "限定技，当你进入濒死状态后，你可以回复1点体力并获得技能〖镇南〗，然后如果你脱离濒死状态且关索不在场，"..
  "你可令一名其他角色选择是否用关索代替其武将并令其摸三张牌",
  ["joy__zhennan"] = "镇南",
  [":joy__zhennan"] = "当有角色使用普通锦囊牌指定目标后，若此牌目标数大于1，你可以对一名其他角色造成1点伤害。",
  ["#joy__wuniang1-choose"] = "武娘：你可以获得一名其他角色的一张牌，其摸一张牌",
  ["#joy__wuniang2-choose"] = "武娘：你可以获得一名其他角色的一张牌，其摸一张牌，关索摸一张牌",
  ["#joy__xushen-choose"] = "许身：你可以令一名其他角色摸三张牌并选择是否变身为欢乐杀关索！",
  ["#joy__xushen-invoke"]= "许身：你可以变身为欢乐杀关索！",
  
}

local zhangqiying = General(extension, "joy__zhangqiying", "qun", 3, 3, General.Female)
local zhenyi = fk.CreateViewAsSkill{
  name = "joy__zhenyi",
  anim_type = "support",
  pattern = "peach",
  prompt = "#joy__zhenyi2",
  card_num = 1,
  card_filter = function(self, to_select, selected)
    return #selected == 0
  end,
  before_use = function(self, player)
    player.room:removePlayerMark(player, "@@faluclub", 1)
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then return nil end
    local c = Fk:cloneCard("peach")
    c.skillName = self.name
    c:addSubcard(cards[1])
    return c
  end,
  enabled_at_play = Util.FalseFunc,
  enabled_at_response = function(self, player)
    return player.phase == Player.NotActive and player:getMark("@@faluclub") > 0
  end,
}
local zhenyi_trigger = fk.CreateTriggerSkill {
  name = "#joy__zhenyi_trigger",
  main_skill = zhenyi,
  events = {fk.AskForRetrial, fk.DamageCaused, fk.Damaged},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(zhenyi.name) then
      if event == fk.AskForRetrial then
        return player:getMark("@@faluspade") > 0
      elseif event == fk.DamageCaused then
        return target == player and player:getMark("@@faluheart") > 0 and data.to ~= player
      elseif event == fk.Damaged then
        return target == player and player:getMark("@@faludiamond") > 0 
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local prompt
    if event == fk.AskForRetrial then
      prompt = "#joy__zhenyi1::"..target.id
    elseif event == fk.DamageCaused then
      prompt = "#joy__zhenyi3::"..data.to.id
    elseif event == fk.Damaged then
      prompt = "#joy__zhenyi4"
    end
    return room:askForSkillInvoke(player, zhenyi.name, nil, prompt)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(zhenyi.name)
    if event == fk.AskForRetrial then
      room:notifySkillInvoked(player, zhenyi.name, "control")
      room:removePlayerMark(player, "@@faluspade", 1)
      local choice = room:askForChoice(player, {"joy__zhenyi_spade", "joy__zhenyi_heart"}, zhenyi.name)
      local new_card = Fk:cloneCard(data.card.name, choice == "joy__zhenyi_spade" and Card.Spade or Card.Heart, 5)
      new_card.skillName = zhenyi.name
      new_card.id = data.card.id
      data.card = new_card
      room:sendLog{
        type = "#ChangedJudge",
        from = player.id,
        to = { data.who.id },
        arg2 = new_card:toLogString(),
        arg = zhenyi.name,
      }
    elseif event == fk.DamageCaused then
      room:notifySkillInvoked(player, zhenyi.name, "offensive")
      room:removePlayerMark(player, "@@faluheart", 1)
      data.damage = data.damage + 1
    elseif event == fk.Damaged then
      room:notifySkillInvoked(player, zhenyi.name, "masochism")
      room:removePlayerMark(player, "@@faludiamond", 1)
      local cards = {}
      table.insertTable(cards, room:getCardsFromPileByRule(".|.|.|.|.|basic"))
      table.insertTable(cards, room:getCardsFromPileByRule(".|.|.|.|.|trick"))
      table.insertTable(cards, room:getCardsFromPileByRule(".|.|.|.|.|equip"))
      if #cards > 0 then
        room:moveCards({
          ids = cards,
          to = player.id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonJustMove,
          proposer = player.id,
          skillName = zhenyi.name,
        })
      end
    end
  end,
}
local dianhua = fk.CreateTriggerSkill{
  name = "joy__dianhua",
  anim_type = "control",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and (player.phase == Player.Start or player.phase == Player.Finish)
  end,
  on_cost = function(self, event, target, player, data)
    local n = 1
    for _, suit in ipairs({"spade", "club", "heart", "diamond"}) do
      if player:getMark("@@falu"..suit) > 0 then
        n = n + 1
      end
    end
    if player.room:askForSkillInvoke(player, self.name) then
      self.cost_data = n
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:askForGuanxing(player, room:getNCards(self.cost_data), nil, {0, 0}, self.name)
  end,
}
zhenyi:addRelatedSkill(zhenyi_trigger)
zhangqiying:addSkill("falu")
zhangqiying:addSkill(zhenyi)
zhangqiying:addSkill(dianhua)
Fk:loadTranslationTable{
  ["joy__zhangqiying"] = "张琪瑛",
  ["#joy__zhangqiying"] = "禳祷西东",

 
  ["joy__zhenyi"] = "真仪",
  [":joy__zhenyi"] = "你可以在以下时机弃置相应的标记来发动以下效果：<br>"..
  "当一张判定牌生效前，你可以弃置“紫微”，然后将判定结果改为♠5或<font color='red'>♥5</font>；<br>"..
  "当你于回合外需要使用【桃】时，你可以弃置“后土”，然后将你的一张手牌当【桃】使用；<br>"..
  "当你对其他角色造成伤害时，你可以弃置“玉清”，此伤害+1；<br>"..
  "当你受到伤害后，你可以弃置“勾陈”，然后你从牌堆中随机获得三种类型的牌各一张。",
  ["joy__dianhua"] = "点化",
  [":joy__dianhua"] = "准备阶段或结束阶段，你可以观看牌堆顶的X张牌（X为你的标记数+1）。若如此做，你将这些牌以任意顺序放回牌堆顶。",
  
  ["#joy__zhenyi1"] = "真仪：你可以弃置♠紫微，将 %dest 的判定结果改为♠5或<font color='red'>♥5</font>",
  ["#joy__zhenyi2"] = "真仪：你可以弃置♣后土，将一张手牌当【桃】使用",
  ["#joy__zhenyi3"] = "真仪：你可以弃置<font color='red'>♥</font>玉清，对 %dest 造成的伤害+1",
  ["#joy__zhenyi4"] = "真仪：你可以弃置<font color='red'>♦</font>勾陈，从牌堆中随机获得三种类型的牌各一张",
  ["#joy__zhenyi_trigger"] = "真仪",
  ["joy__zhenyi_spade"] = "将判定结果改为♠5",
  ["joy__zhenyi_heart"] = "将判定结果改为<font color='red'>♥</font>5",
}

local joy__sunru = General(extension, "joy__sunru", "wu", 3, 3, General.Female)
local joy__xiecui = fk.CreateTriggerSkill{
  name = "joy__xiecui",
  anim_type = "offensive",
  events = {fk.DamageCaused},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and target and not target.dead and target == player.room.current and data.card then
      return player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 and
      #player.room.logic:getActualDamageEvents( 1, function(e) return e.data[1].from == target end) == 0
    end
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, data, "#joy__xiecui-invoke:"..data.from.id..":"..data.to.id)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    data.damage = data.damage + 1
    if not target.dead and target:getHandcardNum() > target.hp and room:getCardArea(data.card) == Card.Processing then
      room:addPlayerMark(target, MarkEnum.AddMaxCardsInTurn, 1)
      room:moveCardTo(data.card, Card.PlayerHand, target, fk.ReasonPrey, self.name)
    end
  end,
}
joy__sunru:addSkill(joy__xiecui)
joy__sunru:addSkill("youxu")
Fk:loadTranslationTable{
  ["joy__sunru"] = "孙茹",
  ["#joy__sunru"] = "呦呦鹿鸣",

  ["joy__xiecui"] = "撷翠",
  [":joy__xiecui"] = "每当一名角色于其回合内使用牌首次造成伤害时，你可令此伤害+1。若该角色手牌数大于等于体力值，其获得此伤害牌且本回合手牌上限+1。",
  ["#joy__xiecui-invoke"] = "撷翠：你可以令 %src 对 %dest造成的伤害+1",

}



local caojinyu = General(extension, "joy__caojinyu", "wei", 3, 3, General.Female)
caojinyu:addSkill("yuqi")
caojinyu:addSkill("shanshen")
caojinyu:addSkill("xianjing")
Fk:loadTranslationTable{
  ["joy__caojinyu"] = "曹金玉",
  ["#joy__caojinyu"] = "金乡公主",

  ["$yuqi_joy__caojinyu1"] = "玉儿摔倒了，要阿娘抱抱。 ",
  ["$yuqi_joy__caojinyu2"] = "这么漂亮的雪花，为什么只能在寒冬呢？ ",
  ["$shanshen_joy__caojinyu1"] = "人家只想做安安静静的小淑女。 ",
  ["$shanshen_joy__caojinyu2"] = " 雪花纷飞，独存寒冬。",
  ["$xianjing_joy__caojinyu1"] = " 得父母之爱，享公主之礼遇。",
  ["$xianjing_joy__caojinyu2"] = " 哼，可不要小瞧女孩子啊。",
  ["~joy__caojinyu"] = "娘亲，雪人不怕冷吗？ ",
}

local fengyu = General(extension, "joy__fengshu", "qun", 3, 3, General.Female)
fengyu:addSkill("tiqi")
fengyu:addSkill("baoshu")
Fk:loadTranslationTable{
  ["joy__fengshu"] = "冯妤",
  ["#joy__fengshu"] = "泣珠伊人",
}

local caohua = General(extension, "joy__caohua", "wei", 3, 3, General.Female)
caohua:addSkill("caiyi")
caohua:addSkill("guili")
Fk:loadTranslationTable{
  ["joy__caohua"] = "曹华",
  ["#joy__caohua"] = "殊凰求凤",
}



local xuelingyun = General(extension, "joy__xuelingyun", "wei", 3, 3, General.Female)
xuelingyun:addSkill("xialei")
xuelingyun:addSkill("anzhi")
Fk:loadTranslationTable{
  ["joy__xuelingyun"] = "薛灵芸",
  ["#joy__xuelingyun"] = "霓裳缀红泪",
}



local quanhuijie = General(extension, "joy__quanhuijie", "wu", 3, 3, General.Female)
local ligong = fk.CreateTriggerSkill{
  name = "joy__ligong",
  frequency = Skill.Wake,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      player.phase == Player.Start and
      player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  can_wake = function(self, event, target, player, data)
    return player:hasSkill("huishu", true) and
    (player:getMark("huishu1") > 1 or player:getMark("huishu2") > 3 or player:getMark("huishu3") > 2)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:changeMaxHp(player, 1)
    room:recover({
      who = player,
      num = 1,
      recoverBy = player,
      skillName = self.name
    })
    room:handleAddLoseSkills(player, "-yishu", nil)
    local generals = {}
    for _, general in pairs(Fk.generals) do
      if general.package.extensionName == "joy" and general.gender == General.Female and general.kingdom == "wu" and general.name ~= "joy__quanhuijie" then
        table.insert(generals, general.name)
      end
    end
    local choices = {}
    if #generals > 0 then 
    generals = table.random(generals, 4)

    local skills = {}
    for _, general_name in ipairs(generals) do
      local general = Fk.generals[general_name]
      local g_skills = {}
      for _, skill in ipairs(general.skills) do
        if not (table.contains({Skill.Limited, Skill.Wake, Skill.Quest}, skill.frequency) or skill.lordSkill) and
        (#skill.attachedKingdom == 0 or (table.contains(skill.attachedKingdom, "wu") and player.kingdom == "wu")) then
          table.insertIfNeed(g_skills, skill.name)
        end
      end
      for _, s_name in ipairs(general.other_skills) do
        local skill = Fk.skills[s_name]
        if not (table.contains({Skill.Limited, Skill.Wake, Skill.Quest}, skill.frequency) or skill.lordSkill) and
        (#skill.attachedKingdom == 0 or (table.contains(skill.attachedKingdom, "wu") and player.kingdom == "wu")) then
          table.insertIfNeed(g_skills, skill.name)
        end
      end
      table.insertIfNeed(skills, g_skills)
    end
    local result = player.room:askForCustomDialog(player, self.name,
    "packages/tenyear/qml/ChooseGeneralSkillsBox.qml", {
      generals, skills, 1, 2, "#ligong-choice", true
    })
    if result ~= "" then
      choices = json.decode(result)
    end
    end
    if #choices == 0 then
      player:drawCards(3, self.name)
    else
      room:handleAddLoseSkills(player, "-huishu|"..table.concat(choices, "|"), nil)
    end
  end,
}
quanhuijie:addSkill("huishu")
quanhuijie:addSkill("yishu")
quanhuijie:addSkill(ligong)
Fk:loadTranslationTable{
  ["joy__quanhuijie"] = "全惠解",
  ["#joy__quanhuijie"] = "春宫早深",

  ["joy__ligong"] = "离宫",
  [":joy__ligong"] = "觉醒技，准备阶段，若〖慧淑〗有数字达到5，你加1点体力上限并回复1点体力，失去〖易数〗，"..
  "然后从随机四个吴国女性武将中选择至多两个技能获得并失去〖慧淑〗（如果不获得技能则改为摸三张牌）。",

}

local fanyufeng = General(extension, "joy__fanyufeng", "qun", 3, 3, General.Female)
fanyufeng:addSkill("bazhan")
fanyufeng:addSkill("jiaoying")
Fk:loadTranslationTable{
  ["joy__fanyufeng"] = "樊玉凤",
  ["#joy__fanyufeng"] = "红鸾寡宿",
}


local panshu = General(extension, "joy__panshu", "wu", 3, 3, General.Female)
panshu:addSkill("zhiren")
panshu:addSkill("yaner")
Fk:loadTranslationTable{
  ["joy__panshu"] = "潘淑",
  ["#joy__panshu"] = "神女",
}




local zhaoyanw = General(extension, "joy__zhaoyanw", "wu", 3, 3, General.Female)
zhaoyanw:addSkill("jinhui")
zhaoyanw:addSkill("qingman")
Fk:loadTranslationTable{
  ["joy__zhaoyanw"] = "赵嫣",
  ["#joy__zhaoyanw"] = "霞蔚青歇",
}

local zhangyao = General(extension, "joy__zhangyao", "wu", 3, 3, General.Female)
zhangyao:addSkill("yuanyu")
zhangyao:addSkill("xiyan")
Fk:loadTranslationTable{
  ["joy__zhangyao"] = "张媱",
  ["#joy__zhangyao"] = "琼楼孤蒂",
}

local lvlingqi = General(extension, "joy__lvlingqi", "qun", 4, 4, General.Female)
lvlingqi:addSkill("guowu")
lvlingqi:addSkill("zhuangrong")
lvlingqi:addRelatedSkill("shenwei")
lvlingqi:addRelatedSkill("wushuang")
Fk:loadTranslationTable{
  ["joy__lvlingqi"] = "吕玲绮",
  ["#joy__lvlingqi"] = "无双虓姬",
  ["$shenwei_joy__lvlingqi1"] = "继父神威，无坚不摧！",
  ["$shenwei_joy__lvlingqi2"] = "我乃温侯吕奉先之女！",
  ["$wushuang_joy__lvlingqi1"] = "猛将策良骥，长戟破敌营。",
  ["$wushuang_joy__lvlingqi2"] = "杀气腾剑戟，严风卷戎装。",
}


local wanniangongzhu = General(extension, "joy__wanniangongzhu", "qun", 3, 3, General.Female)
wanniangongzhu:addSkill("zhenge")
wanniangongzhu:addSkill("xinghan")
Fk:loadTranslationTable{
  ["joy__wanniangongzhu"] = "万年公主",
  ["#joy__wanniangongzhu"] = "还汉明珠",
}

local tenggongzhu = General(extension, "joy__tenggongzhu", "wu", 3, 3, General.Female)
tenggongzhu:addSkill("xingchong")
tenggongzhu:addSkill("liunian")
Fk:loadTranslationTable{
  ["joy__tenggongzhu"] = "滕公主",
  ["#joy__tenggongzhu"] = "芳华荏苒",
}

local zhouyi = General(extension, "joy__zhouyi", "wu", 3, 3, General.Female)
zhouyi:addSkill("zhukou")
zhouyi:addSkill("mengqing")
zhouyi:addRelatedSkill("yuyun")
Fk:loadTranslationTable{
  ["joy__zhouyi"] = "周夷",
  ["#joy__zhouyi"] = "靛情雨黛",
}

local luyi = General(extension, "joy__luyi", "qun", 3, 3, General.Female)

local function searchFuxueCards(room, findOne)
  if #room.discard_pile == 0 then return {} end
  local ids = {}
  local discard_pile = table.simpleClone(room.discard_pile)
  local logic = room.logic
  local events = logic.event_recorder[GameEvent.MoveCards] or Util.DummyTable
  for i = #events, 1, -1 do
    local e = events[i]
    for _, move in ipairs(e.data) do
      for _, info in ipairs(move.moveInfo) do
        local id = info.cardId
        if table.removeOne(discard_pile, id) then
          if move.toArea == Card.DiscardPile and move.moveReason ~= fk.ReasonUse then
            table.insertIfNeed(ids, id)
            if findOne then
              return ids
            end
          end
        end
      end
    end
    if #discard_pile == 0 then break end
  end
  return ids
end

local fuxue = fk.CreateTriggerSkill{
  name = "joy__fuxue",
  anim_type = "drawcard",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if player.phase == Player.Start then
        return #searchFuxueCards(player.room, true) > 0
      elseif player.phase == Player.Finish then
        return player:isKongcheng() or
          table.every(player.player_cards[Player.Hand], function(id) return Fk:getCardById(id):getMark("@@joy__fuxue-inhand") == 0 end)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if player.phase == Player.Start then
      return player.room:askForSkillInvoke(player, self.name, nil, "#joy__fuxue-invoke:::"..player.hp)
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    if player.phase == Player.Start then
      local room = player.room
      local cards = searchFuxueCards(room, false)
      if #cards == 0 then return false end
      table.sort(cards, function (a, b)
        local cardA, cardB = Fk:getCardById(a), Fk:getCardById(b)
        if cardA.type == cardB.type then
          if cardA.sub_type == cardB.sub_type then
            if cardA.name == cardB.name then
              return a > b
            else
              return cardA.name > cardB.name
            end
          else
            return cardA.sub_type < cardB.sub_type
          end
        else
          return cardA.type < cardB.type
        end
      end)
      local get = room:askForCardsChosen(player, player, 1, player.hp, {
        card_data = {
          { self.name, cards }
        }
      }, self.name)
      if #get > 0 then
        local dummy = Fk:cloneCard("dilu")
        dummy:addSubcards(get)
        room:obtainCard(player.id, dummy, true, fk.ReasonJustMove)
        for _, id in ipairs(get) do
          if room:getCardArea(id) == Card.PlayerHand and room:getCardOwner(id) == player then
            room:setCardMark(Fk:getCardById(id), "@@joy__fuxue-inhand", 1)
          end
        end
      end
    else
      player:drawCards(player.hp, self.name)
    end
  end,

  refresh_events = {fk.TurnEnd},
  can_refresh = function(self, event, target, player, data)
    return target == player and not player:isKongcheng()
  end,
  on_refresh = function(self, event, target, player, data)
    for _, id in ipairs(player.player_cards[Player.Hand]) do
      player.room:setCardMark(Fk:getCardById(id), "@@joy__fuxue-inhand", 0)
    end
  end,
}
local yaoyi = fk.CreateTriggerSkill{
  name = "joy__yaoyi",
  anim_type = "special",
  frequency = Skill.Compulsory,
  events = {fk.GameStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(player.room:getAlivePlayers()) do
      local yes = true
      for _, skill in ipairs(p.player_skills) do
        if skill.switchSkillName then
          yes = false
          break
        end
      end
      if yes then
        room:handleAddLoseSkills(p, "joy__shoutan", nil, true, false)
      end
    end
  end,

  refresh_events = {fk.Deathed},
  can_refresh = function(self, event, target, player, data)
    return target == player and player:hasSkill(self, true, true)
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room:getAllPlayers()) do
      room:handleAddLoseSkills(p, "-joy__shoutan", nil, true, true)
    end
  end,
}
local yaoyi_prohibit = fk.CreateProhibitSkill{
  name = "#joy__yaoyi_prohibit",
  frequency = Skill.Compulsory,
  is_prohibited = function(self, from, to, card)
    if table.find(Fk:currentRoom().alive_players, function(p) return p:hasSkill("joy__yaoyi") end) then
      if from ~= to then
        local fromskill = {}
        for _, skill in ipairs(from.player_skills) do
          if skill.switchSkillName then
            table.insertIfNeed(fromskill, skill.switchSkillName)
          end
        end
        local toskill = {}
        for _, skill in ipairs(to.player_skills) do
          if skill.switchSkillName then
            table.insertIfNeed(toskill, skill.switchSkillName)
          end
        end
        if #fromskill == 0 or #toskill == 0 then return false end
        if #fromskill > 1 then  
        end
        return from:getSwitchSkillState(fromskill[1], false) == to:getSwitchSkillState(toskill[1], false)
      end
    end
  end,
}
local shoutan_refresh = fk.CreateTriggerSkill{
  name = "#joy__shoutan_refresh",
  mute = true,
  frequency = Skill.Compulsory,
  events = {fk.AfterCardUseDeclared},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player:getMark("joy__shoutan-phase") > 0 
  end,
  on_use = function(self, event, target, player, data)
    player.room:setPlayerMark(player,"joy__shoutan-phase",0)
  end
}
local shoutan = fk.CreateActiveSkill{
  name = "joy__shoutan",
  anim_type = "switch",
  switch_skill_name = "joy__shoutan",
  card_num = function()
    if Self:hasSkill("joy__yaoyi") then
      return 0
    else
      return 1
    end
  end,
  target_num = 0,
  can_use = function(self, player)
    if player:hasSkill("joy__yaoyi") then
      return true and player:getMark("joy__shoutan-phase") == 0 
    else
      return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
    end
  end,
  card_filter = function(self, to_select, selected)
    if Self:hasSkill("joy__yaoyi") then
      return false
    elseif #selected == 0 and Fk:currentRoom():getCardArea(to_select) ~= Card.PlayerEquip then
      if Self:getSwitchSkillState(self.name, false) == fk.SwitchYang then
        return Fk:getCardById(to_select).color ~= Card.Black
      else
        return Fk:getCardById(to_select).color == Card.Black
      end
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    if player:hasSkill("joy__yaoyi") then
      room:setPlayerMark(player,"joy__shoutan-phase",1)
    end
    room:throwCard(effect.cards, self.name, player, player)
  end,
}
yaoyi:addRelatedSkill(shoutan_refresh)
yaoyi:addRelatedSkill(yaoyi_prohibit)
luyi:addSkill(fuxue)
luyi:addSkill(yaoyi)
luyi:addRelatedSkill(shoutan)
Fk:loadTranslationTable{
  ["joy__luyi"] = "卢弈",
  ["#joy__luyi"] = "落子惊鸿",

  ["joy__fuxue"] = "复学",
  [":joy__fuxue"] = "准备阶段，你可以从弃牌堆中获得至多X张不因使用而进入弃牌堆的牌。结束阶段，若你手中没有以此法获得的牌，你摸X张牌。（X为你的体力值）",
  ["joy__yaoyi"] = "邀弈",
  [":joy__yaoyi"] = "锁定技，游戏开始时，所有没有转换技的角色获得〖手谈〗；你发动〖手谈〗无需弃置牌且无次数限制。"..
  '<br /><font color="grey">（防止永动，每次发动手谈后需使用一张牌后才可再次发动）</font>'..
  "<br>所有角色使用牌只能指定自己及与自己转换技状态不同的角色为目标。",
  ["joy__shoutan"] = "手谈",
  [":joy__shoutan"] = "转换技，出牌阶段限一次，你可以弃置一张：阳：非黑色手牌；阴：黑色手牌。",
  ["#joy__fuxue-invoke"] = "复学：你可以获得弃牌堆中至多%arg张不因使用而进入弃牌堆的牌",
  ["@@joy__fuxue-inhand"] = "复学",
  ["#joy__shoutan_refresh"] = "邀弈",

  ["is_selected"] = "已选择",

  ["$joy__fuxue1"] = " ",
  ["$joy__fuxue2"] = " ",
  ["$joy__yaoyi1"] = " ",
  ["$joy__yaoyi2"] = " ",
  ["$joy__shoutan1"] = " ",
  ["$joy__shoutan2"] = " ",
  ["~joy__luyi"] = " ",
}


local yinfuren = General(extension, "joy__yinfuren", "wei", 3, 3, General.Female)
local yingyu = fk.CreateTriggerSkill{
  name = "joy__yingyu",
  anim_type = "control",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      (player.phase == Player.Play or (player.phase == Player.Finish and player:usedSkillTimes("joy__yongbi", Player.HistoryGame) > 0))
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = table.map(table.filter(room.alive_players, function(p)
      return not p:isKongcheng() end), Util.IdMapper)
    if #targets < 2 then return end
    local tos = room:askForChoosePlayers(player, targets, 2, 2, "#yingyu-choose", self.name, true)
    if #tos == 2 then
      self.cost_data = tos
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local target1 = room:getPlayerById(self.cost_data[1])
    local target2 = room:getPlayerById(self.cost_data[2])
    room:doIndicate(player.id, {self.cost_data[1]})
    local id1 = room:askForCardChosen(player, target1, "h", self.name)
    room:doIndicate(player.id, {self.cost_data[2]})
    local id2 = room:askForCardChosen(player, target2, "h", self.name)
    target1:showCards(id1)
    target2:showCards(id2)
    if Fk:getCardById(id1).suit ~= Fk:getCardById(id2).suit and
      Fk:getCardById(id1).suit ~= Card.NoSuit and Fk:getCardById(id1).suit ~= Card.NoSuit then
      local to = room:askForChoosePlayers(player, self.cost_data, 1, 1, "#yingyu2-choose", self.name, false)
      if #to > 0 then
        to = to[1]
      else
        to = table.random(self.cost_data)
      end
      if to == target1.id then
        room:obtainCard(self.cost_data[1], id2, true, fk.ReasonPrey)
      else
        room:obtainCard(self.cost_data[2], id1, true, fk.ReasonPrey)
      end
    end
  end,
}
local yongbi = fk.CreateActiveSkill{
  name = "joy__yongbi",
  anim_type = "support",
  min_card_num = 1,
  target_num = 1,
  can_use = function(self, player)
    return not player:isKongcheng() and player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  card_filter = function(self, to_select, selected)
    return Fk:currentRoom():getCardArea(to_select) ~= Card.PlayerEquip
  end,
  target_filter = function(self, to_select, selected)
    return #selected == 0 and to_select ~= Self.id 
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local cards = effect.cards
    local dummy = Fk:cloneCard("dilu")
    dummy:addSubcards(cards)
    room:moveCardTo(cards, Player.Hand, target, fk.ReasonGive, self.name, nil, false)
    local suits = {}
    for _, id in ipairs(dummy.subcards) do
      if Fk:getCardById(id, true).suit ~= Card.NoSuit then
        table.insertIfNeed(suits, Fk:getCardById(id, true).suit)
      end
    end
    if #suits > 1 then
      room:addPlayerMark(player, MarkEnum.AddMaxCards, 2)
      room:addPlayerMark(target, MarkEnum.AddMaxCards, 2)
    end
    if #suits > 2 then
      room:setPlayerMark(player, "@@joy__yongbi", 1)
      room:setPlayerMark(target, "@@joy__yongbi", 1)
    end
  end,
}
local yongbi_trigger = fk.CreateTriggerSkill{
  name = "#joy__yongbi_trigger",
  anim_type = "defensive",
  events = {fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:getMark("@@joy__yongbi") > 0 and data.damage > 1
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    data.damage = data.damage - 1
  end,
}
yongbi:addRelatedSkill(yongbi_trigger)
yinfuren:addSkill(yingyu)
yinfuren:addSkill(yongbi)
Fk:loadTranslationTable{
  ["joy__yinfuren"] = "尹夫人",
  ["#joy__yinfuren"] = "委身允翕",

  ["joy__yingyu"] = "媵予",
  [":joy__yingyu"] = "准备阶段，你可以展示两名角色的各一张手牌，若花色不同，则你选择其中的一名角色获得另一名角色的展示牌。（若你已发动过〖拥嬖〗，则结束阶段也可发动此技能）",
  ["joy__yongbi"] = "拥嬖",
  [":joy__yongbi"] = "限定技，出牌阶段，你可将任意手牌交给一名其他角色。根据其中牌的花色数量，"..
  "你与其永久获得以下效果：至少两种，手牌上限+2；至少三种，受到大于1点的伤害时伤害-1。",
  ["@@joy__yongbi"] = "拥嬖",
  ["#joy__yongbi_trigger"] = "拥嬖",
}



local guozhao = General(extension, "joy__guozhao", "wei", 3, 3, General.Female)
guozhao:addSkill("pianchong")
guozhao:addSkill("zunwei")
Fk:loadTranslationTable{
  ["joy__guozhao"] = "郭照",
  ["#joy__guozhao"] = "碧海青天",
}

local laiyinger = General(extension, "joy__laiyinger", "qun", 3, 3, General.Female)
local xiaowu = fk.CreateActiveSkill{
  name = "joy__xiaowu",
  anim_type = "offensive",
  prompt = "#xiaowu",
  max_card_num = 0,
  target_num = 1,
  interaction = function(self)
    return UI.ComboBox { choices = {"xiaowu_clockwise", "xiaowu_anticlockwise"} }
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) < 1
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected, selected_cards)
    return #selected == 0 and to_select ~= Self.id
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local players = room:getOtherPlayers(player)
    local targets = {}
    local choice = self.interaction.data
    for i = 1, #players, 1 do
      local real_i = i
      if choice == "xiaowu_anticlockwise" then
        real_i = #players + 1 - real_i
      end
      local temp = players[real_i]
      table.insert(targets, temp)
      if temp == target then break end
    end
    room:doIndicate(player.id, table.map(targets, Util.IdMapper))
    local x = 0
    local to_damage = {}
    for _, p in ipairs(targets) do
      if not p.dead and not player.dead then
        choice = room:askForChoice(p, {"xiaowu_draw1", "draw1"}, self.name, "#xiawu_draw:" .. player.id)
        if choice == "xiaowu_draw1" then
          player:drawCards(1, self.name)
          x = x+1
        elseif choice == "draw1" then
          p:drawCards(1, self.name)
          table.insert(to_damage, p.id)
        end
      end
    end
    if not player.dead then
      local n = 0
      if x > 0 then
        n = x%2
        n = n + x//2
      end
      room:addPlayerMark(player, "@xiaowu_sand",n)
      if x < #to_damage then
        room:sortPlayersByAction(to_damage)
        for _, pid in ipairs(to_damage) do
          local p = room:getPlayerById(pid)
          if not p.dead then
            room:damage{ from = player, to = p, damage = 1, skillName = self.name }
          end
        end
      end
    end
  end,
}
local huaping = fk.CreateTriggerSkill{
  name = "joy__huaping",
  events = {fk.Death},
  frequency = Skill.Limited,
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self, false, player == target) and player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  on_cost = function(self, event, target, player, data)
    if player == target then
      local to = player.room:askForChoosePlayers(player, table.map(player.room:getOtherPlayers(player), Util.IdMapper), 1, 1, "#huaping-choose", self.name, true)
      if #to > 0 then
        self.cost_data = to[1]
        return true
      end
    else
      return player.room:askForSkillInvoke(player, self.name, nil, "#huaping-invoke::"..target.id)
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if player == target then
      local to = room:getPlayerById(self.cost_data)
      room:handleAddLoseSkills(to, "shawu", nil, true, false)
      room:setPlayerMark(to, "@xiaowu_sand", player:getMark("@xiaowu_sand"))
    else
      local skills = {}
      for _, s in ipairs(target.player_skills) do
        if not (s.attached_equip or s.name[#s.name] == "&") then
          table.insertIfNeed(skills, s.name)
        end
      end
      if #skills > 0 then
        room:handleAddLoseSkills(player, table.concat(skills, "|"), nil, true, false)
      end
      local x = player:getMark("@xiaowu_sand")
      room:handleAddLoseSkills(player, "-joy__xiaowu", nil, true, false)
      room:setPlayerMark(player, "@xiaowu_sand", 0)
      if x > 0 then
        player:drawCards(x, self.name)
      end
    end
  end,
}
local shawu_select = fk.CreateActiveSkill{
  name = "joy__shawu_select",
  can_use = Util.FalseFunc,
  target_num = 0,
  max_card_num = 2,
  min_card_num = function ()
    if Self:getMark("@xiaowu_sand") > 0 then
      return 0
    end
    return 2
  end,
  card_filter = function(self, to_select, selected)
    return #selected < 2 and not Self:prohibitDiscard(Fk:getCardById(to_select)) and Fk:currentRoom():getCardArea(to_select) ~= Player.Equip
  end,
}
Fk:addSkill(shawu_select)
laiyinger:addSkill(xiaowu)
laiyinger:addSkill(huaping)
laiyinger:addRelatedSkill("shawu")
Fk:loadTranslationTable{
  ["joy__laiyinger"] = "来莺儿",
  ["#joy__laiyinger"] = "雀台歌女",

  ["joy__xiaowu"] = "绡舞",
  [":joy__xiaowu"] = "出牌阶段限一次，你可以从你的上家或下家起选择任意名座位连续的其他角色，每名角色依次选择一项：1.令你摸一张牌；2.自己摸一张牌。"..
  "选择完成后，你获得X个“沙”标记(X为选择令你摸牌的角色数的一半，向上取整）；若自己摸牌的选择人数较多，你对这些角色各造成1点伤害。",
  ["joy__huaping"] = "化萍",
  [":joy__huaping"] = "限定技，一名其他角色死亡时，你可以获得其所有武将技能，然后你失去〖绡舞〗和所有“沙”标记并摸等量的牌。"..
  "你死亡时，若此技能未发动过，你可令一名其他角色获得技能〖沙舞〗和所有“沙”标记。",
}



local yanfuren = General(extension, "joy__yanfuren", "qun", 3, 3, General.Female)
local channi_viewas = fk.CreateViewAsSkill{
  name = "joy__channi_viewas",
  anim_type = "offensive",
  pattern = "duel",
  card_filter = function(self, to_select, selected)
    return Fk:currentRoom():getCardArea(to_select) ~= Player.Equip and #selected < Self:getMark("joy__channi")
  end,
  view_as = function(self, cards)
    if #cards == 0 then return end
    local card = Fk:cloneCard("duel")
    card:addSubcards(cards)
    card.skillName = "joy__channi"
    return card
  end,
}
local channi = fk.CreateActiveSkill{
  name = "joy__channi",
  anim_type = "support",
  prompt = "#channi-active",
  min_card_num = 1,
  target_num = 1,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = function(self, to_select, selected)
    return Fk:currentRoom():getCardArea(to_select) ~= Card.PlayerEquip
  end,
  target_filter = function(self, to_select, selected)
    return #selected == 0 and to_select ~= Self.id
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local n = #effect.cards
    room:moveCardTo(effect.cards, Player.Hand, target, fk.ReasonGive, self.name, nil, false, player.id)
    room:setPlayerMark(target, self.name, n)
    local success, data = room:askForUseActiveSkill(target, "joy__channi_viewas", "#joy__channi-invoke:"..player.id.."::"..n, true, {}, false)
    room:setPlayerMark(target, self.name, 0)
    if success then
      local card = Fk:cloneCard("duel")
      card.skillName = self.name
      card:addSubcards(data.cards)
      local use = {
        from = target.id,
        tos = table.map(data.targets, function(id) return {id} end),
        card = card,
        extra_data = {channi_data = {player.id, target.id, #data.cards}}
      }
      room:useCard(use)
    end
  end,
}
local channi_delay = fk.CreateTriggerSkill{
  name = "#joy__channi_delay",
  events = {fk.Damage, fk.DamageInflicted},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if not player.dead and target and not target.dead and data.card and not data.chain and
    table.contains(data.card.skillNames, channi.name) then
      local room = player.room
      local card_event = room.logic:getCurrentEvent():findParent(GameEvent.UseCard)
      if not card_event then return false end
      local use = card_event.data[1]
      if use.extra_data then
        local channi_data = use.extra_data.channi_data
        if channi_data and channi_data[1] == player.id and channi_data[2] == target.id then
          self.cost_data = channi_data[3]
          return true
        end
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.Damage then
      room:notifySkillInvoked(player, channi.name, "drawcard")
      room:doIndicate(player.id, {target.id})
      room:drawCards(target, self.cost_data, channi.name)
    else
      local cards = player.player_cards[Player.Hand]
      if #cards > 0 then
        if room:askForSkillInvoke(player,self.name,data,"#joy__channi_damaged") then
          room:notifySkillInvoked(player, "joy__channi", "negative")
          room:throwCard(cards,self.name,player)
          return true
        end
      end
    end
  end
}

local nifu = fk.CreateTriggerSkill{
  name = "joy__nifu",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player:getHandcardNum() ~= 3
  end,
  on_use = function(self, event, target, player, data)
    local n = player:getHandcardNum() - 3
    if n < 0 then
      player:drawCards(-n, self.name)
    else
      player.room:askForDiscard(player, n, n, false, self.name, false)
    end
  end,
}
Fk:addSkill(channi_viewas)
channi:addRelatedSkill(channi_delay)
yanfuren:addSkill(channi)
yanfuren:addSkill(nifu)
Fk:loadTranslationTable{
  ["joy__yanfuren"] = "严夫人",
  ["#joy__yanfuren"] = "霜天薄裳",

  ["joy__channi"] = "谗逆",
  [":joy__channi"] = "出牌阶段限一次，你可以交给一名其他角色任意张手牌，然后该角色可以将至多等量张手牌当一张【决斗】使用。"..
  "其因此使用【决斗】造成伤害后，其摸X张牌；其因此使用【决斗】受到伤害时，你可以弃置所有手牌（至少为1）防止此伤害。",
  ["joy__nifu"] = "匿伏",
  [":joy__nifu"] = "锁定技，每个回合结束时，你将手牌摸至或弃置至三张。",
  ["#joy__channi-invoke"] = "谗逆：你可以将至多%arg张手牌当一张【决斗】使用<br>若对目标造成伤害你摸等量牌",
  ["#joy__channi_damaged"] = "馋逆：是否弃置所有手牌防止此【决斗】的伤害",
  ["joy__channi_viewas"] = "馋逆",
  ["#joy__channi_delay"] = "馋逆",

}

local xiahoulingnv = General(extension, "joy__xiahoulingnv", "wei", 4, 4, General.Female)
local fuping = fk.CreateViewAsSkill{
  name = "joy__fuping",
  anim_type = "special",
  pattern = ".",
  prompt = "#fuping-viewas",
  interaction = function()
    if type(Self:getMark("@$fuping")) ~= "table" then return end
    local all_names, names = Self:getMark("@$fuping"), {}
    local used_names = type(Self:getMark("fuping-turn")) == "table" and Self:getMark("fuping-turn") or {}
    for _, name in ipairs(all_names) do
      if not table.contains(used_names, name) then
        local to_use = Fk:cloneCard(name)
        to_use.skillName = "fuping"
        if ((Fk.currentResponsePattern == nil and Self:canUse(to_use) and not Self:prohibitUse(to_use)) or
          (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(to_use))) then
          table.insertIfNeed(names, name)
        end
      end
    end
    if #names == 0 then return end
    return UI.ComboBox {choices = names, all_choices = all_names}
  end,
  card_filter = function(self, to_select, selected)
    return #selected < 1 and Fk:getCardById(to_select).type ~= Card.TypeBasic
  end,
  view_as = function(self, cards)
    if #cards ~= 1 or not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    card:addSubcard(cards[1])
    card.skillName = self.name
    return card
  end,
  enabled_at_play = function(self, player)
    local names = player:getMark("@$fuping")
    if type(names) ~= "table" then return false end
    local used_names = type(player:getMark("fuping-turn")) == "table" and player:getMark("fuping-turn") or {}
    for _, name in ipairs(names) do
      if not table.contains(used_names, name) then
        local to_use = Fk:cloneCard(name)
        to_use.skillName = self.name
        if player:canUse(to_use) and not player:prohibitUse(to_use) then
          return true
        end
      end
    end
  end,
  enabled_at_response = function(self, player, response)
    local names = player:getMark("@$fuping")
    if type(names) ~= "table" then return false end
    local used_names = type(player:getMark("fuping-turn")) == "table" and player:getMark("fuping-turn") or {}
    for _, name in ipairs(names) do
      if not table.contains(used_names, name) then
        local to_use = Fk:cloneCard(name)
        to_use.skillName = self.name
        if (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(to_use)) then
          return true
        end
      end
    end
  end,
  before_use = function(self, player, useData)
    local names = type(player:getMark("fuping-turn")) == "table" and player:getMark("fuping-turn") or {}
    table.insert(names, useData.card.trueName)
    player.room:setPlayerMark(player, "fuping-turn", names)
  end,
}
local fuping_trigger = fk.CreateTriggerSkill{
  name = "#joy__fuping_trigger",
  events = {fk.CardUseFinished},
  main_skill = fuping,
  can_trigger = function(self, event, target, player, data)
    if target == player or not player:hasSkill(fuping.name) or #player:getAvailableEquipSlots() == 0 then return false end
    if data.card.type ~= Card.TypeEquip and table.contains(TargetGroup:getRealTargets(data.tos), player.id) then
      local mark = player:getMark("@$fuping")
      return type(mark) ~= "table" or not table.contains(mark, data.card.trueName)
    end
  end,
  on_cost = function(self, event, target, player, data)
    local all_choices = {"WeaponSlot", "ArmorSlot", "DefensiveRideSlot", "OffensiveRideSlot", "TreasureSlot"}
    local subtypes = {Card.SubtypeWeapon, Card.SubtypeArmor, Card.SubtypeDefensiveRide, Card.SubtypeOffensiveRide, Card.SubtypeTreasure}
    local choices = {}
    for i = 1, 5, 1 do
      if #player:getAvailableEquipSlots(subtypes[i]) > 0 then
        table.insert(choices, all_choices[i])
      end
    end
    table.insert(all_choices, "Cancel")
    table.insert(choices, "Cancel")
    local choice = player.room:askForChoice(player, choices, fuping.name, "#fuping-choice:::" .. data.card.trueName, false, all_choices)
    if choice ~= "Cancel" then
      self.cost_data = choice
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(fuping.name)
    room:abortPlayerArea(player, {self.cost_data})
    local mark = type(player:getMark("@$fuping")) == "table" and player:getMark("@$fuping") or {}
    table.insertIfNeed(mark, data.card.trueName)
    room:setPlayerMark(player, "@$fuping", mark)
  end,
}
local fuping_targetmod = fk.CreateTargetModSkill{
  name = "#joy__fuping_targetmod",
  bypass_distances = function(self, player, skill, card, to)
    return player:hasSkill(fuping.name) and #player:getAvailableEquipSlots() == 1
  end,
}
local weilie = fk.CreateActiveSkill{
  name = "joy__weilie",
  anim_type = "support",
  prompt = function ()
    local max_times = type(Self:getMark("@$fuping")) == "table" and #Self:getMark("@$fuping") or 0
    return "#joy__weilie-active:::" .. tostring(max_times - Self:usedSkillTimes("weilie", Player.HistoryGame) + 1)
  end,
  can_use = function(self, player)
    local max_times = type(player:getMark("@$fuping")) == "table" and #player:getMark("@$fuping") or 0
    return player:usedSkillTimes(self.name, Player.HistoryGame)  <= max_times
  end,
  card_filter = function(self, to_select, selected, targets)
    return #selected == 0
  end,
  target_filter = function(self, to_select, selected, cards)
    return #selected == 0 and Fk:currentRoom():getPlayerById(to_select):isWounded()
  end,
  target_num = 1,
  card_num = 1,
  on_use = function(self, room, effect)
    local from = room:getPlayerById(effect.from)
    room:throwCard(effect.cards, self.name, from, from)
    local target = room:getPlayerById(effect.tos[1])
    room:recover({
      who = target,
      num = 1,
      recoverBy = from,
      skillName = self.name
    })
    if not target.dead then
      room:drawCards(target, 1, self.name)
    end
  end,
}
fuping:addRelatedSkill(fuping_trigger)
fuping:addRelatedSkill(fuping_targetmod)
xiahoulingnv:addSkill(fuping)
xiahoulingnv:addSkill(weilie)
Fk:loadTranslationTable{
  ["joy__xiahoulingnv"] = "夏侯令女",
  ["#joy__xiahoulingnv"] = "女义如山",
  ["joy__fuping"] = "浮萍",
  [":joy__fuping"] = "当其他角色以你为目标的基本牌或锦囊牌牌结算后，若你未记录此牌，你可以废除一个装备栏并记录此牌。"..
  "你可以将一张非基本牌当记录的牌使用或打出（每种牌名每回合限一次）。若你的装备栏均已废除，你使用牌无距离限制。",
  ["joy__weilie"] = "炜烈",
  [":joy__weilie"] = "每局游戏限一次，出牌阶段，你可以弃置一张牌令一名角色回复1点体力并摸一张牌。你每次发动〖浮萍〗记录牌名时，"..
  "此技能可发动次数+1。",
  ["#joy__fuping_trigger"] = "浮萍",
  ["#joy__weilie-active"] = "发动 炜烈，弃置一张牌令一名已受伤的角色回复体力（剩余 %arg 次）并摸1张牌",

}






local luyusheng = General(extension, "joy__luyusheng", "wu", 3, 3, General.Female)
local zhente = fk.CreateTriggerSkill{
  name = "joy__zhente",
  anim_type = "defensive",
  events = {fk.TargetConfirmed},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and data.from ~= player.id then
      return data.card:isCommonTrick() or data.card.type == Card.TypeBasic
    end
  end,
  on_cost = function(self, event, target, player, data)
    if player.room:askForSkillInvoke(player, self.name, nil,
    "#zhente-invoke:".. data.from .. "::" .. data.card:toLogString() .. ":" .. data.card:getColorString()) then
      player.room:doIndicate(player.id, {data.from})
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(data.from)
    local color = data.card:getColorString()
    local choice = room:askForChoice(to, {
      "zhente_negate::" .. tostring(player.id) .. ":" .. data.card.name,
      "zhente_colorlimit:::" .. color
    }, self.name)
    if choice:startsWith("zhente_negate") then
      table.insertIfNeed(data.nullifiedTargets, player.id)
    else
      local colorsRecorded = type(to:getMark("@zhente-turn")) == "table" and to:getMark("@zhente-turn") or {}
      table.insertIfNeed(colorsRecorded, color)
      room:setPlayerMark(to, "@zhente-turn", colorsRecorded)
    end
  end,
}
local zhente_prohibit = fk.CreateProhibitSkill{
  name = "#joy__zhente_prohibit",
  prohibit_use = function(self, player, card)
    local mark = player:getMark("@zhente-turn")
    return type(mark) == "table" and table.contains(mark, card:getColorString())
  end,
}
local zhiwei = fk.CreateTriggerSkill{
  name = "joy__zhiwei",
  events = {fk.GameStart, fk.TurnStart, fk.AfterCardsMove, fk.Damage, fk.Damaged},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.GameStart then
        return true
      elseif event == fk.TurnStart then
        return player == target and player:getMark(self.name) == 0
      elseif event == fk.AfterCardsMove then
        if player.phase ~= Player.Discard then return false end
        local zhiwei_id = player:getMark(self.name)
        if zhiwei_id == 0 then return false end
        local room = player.room
        local to = room:getPlayerById(zhiwei_id)
        if to == nil or to.dead then return false end
        for _, move in ipairs(data) do
          if move.from == player.id and move.moveReason == fk.ReasonDiscard then
            for _, info in ipairs(move.moveInfo) do
              if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
              room:getCardArea(info.cardId) == Card.DiscardPile then
                return true
              end
            end
          end
        end
      elseif event == fk.Damage then
        return target ~= nil and not target.dead and player:getMark(self.name) == target.id
      elseif event == fk.Damaged then
        return target ~= nil and not target.dead and player:getMark(self.name) == target.id and not player:isKongcheng()
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#zhiwei-choose", self.name, true, true)
      if #to > 0 then
        self.cost_data = to[1]
        return true
      end
      return false
    elseif event == fk.Damaged then
      local card = room:askForCard(player,1,1,false,self.name,true,".","#joy__zhiwei-give")
      if #card > 0 then
        self.cost_data = card
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      room:notifySkillInvoked(player, self.name, "special")
      player:broadcastSkillInvoke(self.name)
      room:setPlayerMark(player, self.name, self.cost_data)
    elseif event == fk.GameStart then
      room:notifySkillInvoked(player, self.name, "special")
      player:broadcastSkillInvoke(self.name)
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      if #targets == 0 then return false end
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#zhiwei-choose", self.name, false, true)
      if #to > 0 then
        room:setPlayerMark(player, self.name, to[1])
      end
    elseif event == fk.AfterCardsMove then
      local zhiwei_id = player:getMark(self.name)
      if zhiwei_id == 0 then return false end
      local to = room:getPlayerById(zhiwei_id)
      if to == nil or to.dead then return false end
      local cards = {}
      for _, move in ipairs(data) do
        if move.from == player.id and move.moveReason == fk.ReasonDiscard then
          for _, info in ipairs(move.moveInfo) do
            if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
            room:getCardArea(info.cardId) == Card.DiscardPile then
              table.insertIfNeed(cards, info.cardId)
            end
          end
        end
      end
      if #cards > 0 then
        player:showCards(cards)
        if room:askForSkillInvoke(player,self.name,data,"#joy__zhiwei-discard") then
          room:notifySkillInvoked(player, self.name, "support")
          player:broadcastSkillInvoke(self.name)
          room:setPlayerMark(player, "@joy__zhiwei", to.general)
          room:moveCards({
          ids = cards,
          to = zhiwei_id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonPrey,
          proposer = player.id,
          skillName = self.name,
          })
        end
      end
    elseif event == fk.Damage then
      room:notifySkillInvoked(player, self.name, "drawcard")
      player:broadcastSkillInvoke(self.name)
      room:setPlayerMark(player, "@joy__zhiwei", target.general)
      room:drawCards(player, 1, self.name)
    elseif event == fk.Damaged then
      local card = self.cost_data[1]
      if not target.dead then
        room:obtainCard(target,card,false,fk.ReasonGive)
      end
    end
  end,

  refresh_events = {fk.BuryVictim},
  can_refresh = function(self, event, target, player, data)
    return player:getMark(self.name) == target.id
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, self.name, 0)
    room:setPlayerMark(player, "@joy__zhiwei", 0)
  end,
}
zhente:addRelatedSkill(zhente_prohibit)
luyusheng:addSkill(zhente)
luyusheng:addSkill(zhiwei)
Fk:loadTranslationTable{
  ["joy__luyusheng"] = "陆郁生",
  ["#joy__luyusheng"] = "义姑",

  ["joy__zhente"] = "贞特",
  [":joy__zhente"] = "当你成为其他角色使用基本牌或普通锦囊牌的目标后，你可令其选择一项：1.本回合不能再使用此颜色的牌；2.此牌对你无效。",
  ["joy__zhiwei"] = "至微",
  [":joy__zhiwei"] = "游戏开始时，你选择一名其他角色，该角色造成伤害后，你摸一张牌；该角色受到伤害后，你可以给予其一张手牌。"..
  "你弃牌阶段弃置的牌可以给予该角色。准备阶段，若场上没有“至微”角色，你可以重新选择一名其他角色。",
  ["#joy__zhiwei-give"] = "至微：是否给予“至微”角色一张手牌？",
  ["#joy__zhiwei-discard"] = "至微：是否将你弃牌阶段弃置的牌全部给予“至微”角色？",
  ["@joy__zhiwei"] = "至微",

  ["$joy__zhente1"] = " ",
  ["$joy__zhente2"] = " ",
  ["$joy__zhiwei1"] = " ",
  ["$joy__zhiwei2"] = " ",
  ["~joy__luyusheng"] = " ",
}



local zhangning = General(extension, "joy__zhangning", "qun", 3, 3, General.Female)
local tianze = fk.CreateTriggerSkill{
  name = "joy__tianze",
  events = {fk.CardUseFinished},
  anim_type = "offensive",
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target ~= player and target.phase == Player.Play and data.card.color == Card.Black and
    player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 and not player:isNude()
  end,
  on_cost = function(self, event, target, player, data)
    local card = player.room:askForDiscard(player, 1, 1, true, self.name, true, ".|.|spade,club|hand,equip", "#joy__tianze-invoke::"..target.id, true)
    if #card > 0 then
      self.cost_data = card
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:doIndicate(player.id, {target.id})
    room:throwCard(self.cost_data, self.name, player, player)
    room:damage{ from = player, to = target, damage = 1, skillName = self.name}
  end,
}
local tianze_draw = fk.CreateTriggerSkill{
  name = "#joy__tianze_draw",
  events = {fk.FinishJudge},
  anim_type = "drawcard",
  mute = true,
  can_trigger = function(self, event, target, player, data)
    return target ~= player and player:hasSkill(tianze.name) and data.card.color == Card.Black
  end,
  on_cost = function() return true end,
  on_use = function(self, event, target, player, data)
    player:broadcastSkillInvoke(tianze.name)
    player.room:notifySkillInvoked(player, tianze.name, self.anim_type)
    player.room:drawCards(player, 1, self.name)
  end,
}
local difa = fk.CreateActiveSkill{
  name = "joy__difa",
  anim_type = "drawcard",
  prompt = "#joy__difa",
  can_use = function(self, player)
    return not player:isKongcheng() and player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_num = 1,
  card_filter = function(self, to_select, selected)
    return #selected < 1 and Fk:getCardById(to_select).color == Card.Red
  end,
  target_num = 0,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:moveCards({
      ids = effect.cards,
      from = player.id,
      toArea = Card.DiscardPile,
      skillName = self.name,
      moveReason = fk.ReasonPutIntoDiscardPile,
      proposer = player.id
    })
    if player.dead then return end
    player:drawCards(1,self.name)
    local allCardMapper = {}
    local allCardNames = {}
    for _, id in ipairs(Fk:getAllCardIds()) do
      local card = Fk:getCardById(id)
      if  card.type == Card.TypeTrick and room:getCardArea(id) == Card.DrawPile then
        if allCardMapper[card.name] == nil then
          allCardMapper[card.name] = {}
          table.insert(allCardNames, card.name)
        end
        table.insert(allCardMapper[card.name], id)
      end
    end
    if #allCardNames == 0 then return end
    local cardName = room:askForChoice(player, allCardNames, self.name)
    room:moveCardTo(table.random(allCardMapper[cardName]), Card.PlayerHand, player, fk.ReasonPrey, self.name)
  end,
}
tianze:addRelatedSkill(tianze_draw)
zhangning:addSkill(tianze)
zhangning:addSkill(difa)
Fk:loadTranslationTable{
  ["joy__zhangning"] = "张宁",
  ["#joy__zhangning"] = "大贤后人",

  ["joy__tianze"] = "天则",
  [":joy__tianze"] = "每回合限一次，当其他角色于其出牌阶段内使用一张黑色牌结算后，你可以弃置一张黑色牌对其造成1点伤害；其他角色的黑色判定牌生效后，你摸一张牌。",
  ["joy__difa"] = "地法",
  [":joy__difa"] = "出牌阶段限一次，你可以重铸一张红色牌，然后声明一种锦囊牌的牌名，从牌堆获得一张。",

  ["#joy__tianze-invoke"] = "天则：每回合限一次，你可弃置一张黑色牌来对%dest造成1点伤害",
  ["#joy__difa"] = "地法：你可重铸一张红色牌，然后检索一张锦囊牌",
  ["$joy__tianze1"] = " ",
  ["$joy__tianze2"] = " ",
  ["$joy__difa1"] = " ",
  ["$joy__difa2"] = " ",
  ["~joy__zhangning"] = " ",
}






local bianfuren = General(extension, "joy__bianfuren", "wei", 3, 3, General.Female)
local wanwei = fk.CreateTriggerSkill{
  name = "joy__wanwei",
  anim_type = "support",
  events = {fk.EnterDying, fk.AfterDying},
  can_trigger = function(self, event, target, player, data)
    if event == fk.EnterDying then
      return player:hasSkill(self) and target ~= player and not player:isNude() and
        player:usedSkillTimes(self.name, Player.HistoryRound) == 0
    else
      return not target.dead and data.extra_data and data.extra_data.ofl__fuding and data.extra_data.ofl__fuding[1] == player.id and
        not player.dead
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.EnterDying then
      local cards = player.room:askForCard(player, 1, 5, true, self.name, true, ".", "#joy__wanwei-invoke::"..target.id)
      if #cards > 0 then
        self.cost_data = cards
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EnterDying then
      room:moveCardTo(self.cost_data, Card.PlayerHand, target, fk.ReasonGive, self.name)
      data.extra_data = data.extra_data or {}
      data.extra_data.ofl__fuding = {player.id, #self.cost_data}
    else
      player:drawCards(data.extra_data.ofl__fuding[2], self.name)
      if player:isWounded() and not player.dead then
        room:recover{
          who = player,
          num = 1,
          recoverBy = player,
          skillName = self.name
        }
      end
    end
  end,
}
local yuejian = fk.CreateViewAsSkill{
  name = "joy__yuejian",
  pattern = ".|.|.|.|.|basic",
  prompt = "#joy__yuejian",
  interaction = function()
    local names = {}
    for _, id in ipairs(Fk:getAllCardIds()) do
      local card = Fk:getCardById(id)
      if card.type == Card.TypeBasic and not card.is_derived then
        local to_use = Fk:cloneCard(card.name)
        if ((Fk.currentResponsePattern == nil and Self:canUse(to_use) and not Self:prohibitUse(to_use)) or
        (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(to_use))) then
          table.insertIfNeed(names, card.name)
        end
      end
    end
    return UI.ComboBox { choices = names }
  end,
  card_filter = function(self, to_select, selected)
    return false
  end,
  view_as = function(self, cards)
    if not self.interaction.data then return nil end
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    return card
  end,
  enabled_at_play = function(self, player)
    return player:getMark("joy__yuejian-turn") == 0
  end,
  enabled_at_response = function(self, player, response)
    return not response and player:getMark("joy__yuejian-turn") == 0
  end,
}
local yuejian_record = fk.CreateTriggerSkill{
  name = "#joy__yuejian_record",

  refresh_events = {fk.AfterCardUseDeclared, fk.EventAcquireSkill},
  can_refresh = function(self, event, target, player, data)
    if event == fk.AfterCardUseDeclared then
      return target == player and data.card.type == Card.TypeBasic and player:getMark("joy__yuejian-turn") == 0
    elseif target == player and data == self and player:getMark("joy__yuejian-turn") == 0 then
      return #player.room.logic:getEventsOfScope(GameEvent.UseCard, 1, function(e)
        local use = e.data[1]
        return use.from == player.id and use.card.type == Card.TypeBasic
      end, Player.HistoryRound) > 0
    end
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:setPlayerMark(player, "joy__yuejian-turn", 1)
  end,
}
local yuejian_maxcards = fk.CreateMaxCardsSkill{
  name = "#joy__yuejian_maxcards",
  frequency = Skill.Compulsory,
  correct_func = function(self, player)
    if player:hasSkill("joy__yuejian") then
      return player.maxHp
    else
      return 0
    end
  end,
}
yuejian:addRelatedSkill(yuejian_record)
yuejian:addRelatedSkill(yuejian_maxcards)
bianfuren:addSkill(wanwei)
bianfuren:addSkill(yuejian)
Fk:loadTranslationTable{
  ["joy__bianfuren"] = "卞夫人",
  ["#joy__bianfuren"] = "内助贤后",

  ["joy__wanwei"] = "挽危",
  [":joy__wanwei"] = "每轮限一次，当一名其他角色进入濒死状态时，你可以交给其至多五张牌，若如此做，当其脱离濒死状态时，你摸等量牌并回复1点体力。",
  ["joy__yuejian"] = "约俭",
  [":joy__yuejian"] = "你的手牌上限+X（X为你的体力上限）。当你需使用一张基本牌时，若你本回合未使用过基本牌，你可以视为使用之。",
  ["#joy__wanwei-invoke"] = "挽危：你可以交给 %dest 至多五张牌，其脱离濒死状态后你摸等量牌并回复1点体力",
  ["#joy__yuejian"] = "约俭：你可以视为使用一张基本牌",
}

local dufuren = General(extension, "joy__dufuren", "wei", 3, 3, General.Female)
local yise = fk.CreateTriggerSkill{
  name = "joy__yise",
  anim_type = "control",
  events = {fk.AfterCardsMove},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      for _, move in ipairs(data) do
        if move.from == player.id and move.to and move.to ~= player.id and move.toArea == Card.PlayerHand then
          self.yise_to = move.to
          for _, info in ipairs(move.moveInfo) do
            self.yise_color = Fk:getCardById(info.cardId).color
              return true
          end
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if self.yise_color == Card.Red then
      return player.room:askForSkillInvoke(player, self.name, data, "#joy__yise-invoke1::"..self.yise_to)
    else
      return player.room:askForSkillInvoke(player, self.name, data, "#joy__yise-invoke3::"..self.yise_to)
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.yise_to)
    if self.yise_color == Card.Red then
      local choices = {"joy__yiseDrawCard","joy__yisecancel"}
      if to:isWounded() then
        table.insert(choices,"joy__yiseCover")
      end
      local choice = player.room:askForChoice(player,choices,self.name)
      if choice == "joy__yiseDrawCard" and not player.dead then
        player:drawCards(1,self.name)
      elseif choice == "joy__yiseCover" then
        room:recover({
          who = to,
          num = 1,
          recoverBy = player,
          skillName = self.name
        })
      else
        return
      end
    elseif self.yise_color == Card.Black then
      room:addPlayerMark(to, "@joy__yise", 1)
    end
  end,
}
local yise_delay = fk.CreateTriggerSkill{
  name = "#joy__yise_delay",
  mute = true,
  frequency = Skill.Compulsory,
  events = {fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:getMark("@joy__yise") > 0 and data.card and data.card.trueName == "slash"
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    data.damage = data.damage + player:getMark("@joy__yise")
    player.room:setPlayerMark(player, "@joy__yise", 0)
  end,
}
local shunshi = fk.CreateTriggerSkill{
  name = "joy__shunshi",
  anim_type = "control",
  events = {fk.EventPhaseStart, fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if event == fk.EventPhaseStart and not player:isNude() then
        return player.phase == Player.Start
      elseif event == fk.Damaged and not player:isNude() and player.room.current ~= player  then
        return true
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = {}
    for _, p in ipairs(room:getOtherPlayers(player)) do
        table.insert(targets, p.id)
    end
    local tos, id = room:askForChooseCardAndPlayers(player, targets, 1, 1, ".", "#shunshi-cost", self.name, true)
    if #tos > 0 then
      self.cost_data = {tos[1], id}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
      room:obtainCard(self.cost_data[1], self.cost_data[2], false, fk.ReasonGive)
      room:addPlayerMark(player, "@joy__shunshi_drawcards", 1)
      room:addPlayerMark(player, "@joy__shunshi_slash", 1)
      room:addPlayerMark(player, "@joy__shunshi_maxcard", 1)
  end,

  refresh_events = { fk.EventPhaseEnd },
  can_refresh = function(self, event, target, player, data)
      return (player.phase == Player.Play and player:getMark("@joy__shunshi_slash") ~= 0) or (player.phase == Player.Discard and player:getMark("@joy__shunshi_maxcard") ~= 0)
  end,
  on_refresh = function(self, event, target, player, data)
    if player.phase == Player.Play then
      player.room:setPlayerMark(player, "@joy__shunshi_slash", 0)
    elseif player.phase == Player.Discard then
      player.room:setPlayerMark(player, "@joy__shunshi_maxcard", 0)
    end
  end,

}
local shunshi_delay = fk.CreateTriggerSkill{
  name = "#joy__shunshi_delay",
  mute = true,
  events = {fk.DrawNCards},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:getMark("@joy__shunshi_drawcards") > 0
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    data.n = data.n + player:getMark("@joy__shunshi_drawcards")
    player.room:setPlayerMark(player, "@joy__shunshi_drawcards", 0)
  end,
}
local shunshi_targetmod = fk.CreateTargetModSkill{
  name = "#joy__shunshi_targetmod",
  residue_func = function(self, player, skill, scope)
    if skill.trueName == "slash_skill" and scope == Player.HistoryPhase then
      return player:getMark("@joy__shunshi_slash")
    end
  end,
}
local shunshi_maxcards = fk.CreateMaxCardsSkill{
  name = "#joy__shunshi_maxcards",
  correct_func = function(self, player)
    return player:getMark("@joy__shunshi_maxcard")
  end,
}

local shunshi_armor = fk.CreateTriggerSkill{
  name = "#joy__shunshi_armor",
  mute = true,
  main_skill = shunshi,
  events = {fk.AfterCardTargetDeclared},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill("joy__shunshi") and player.phase == Player.Play and player:getMark("@joy__shunshi_slash") > 0 then
      return data.card.trueName == "slash" 
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local card_event = room.logic:getCurrentEvent():findParent(GameEvent.UseCard)
    card_event.joy__shunshi_armor = true
    for _, p in ipairs(room.alive_players) do
      room:addPlayerMark(p, fk.MarkArmorNullified)
    end
end,

refresh_events = {fk.CardUseFinished},
can_refresh = function(self, event, target, player, data)
  if player ~= target then return false end
  local card_event = player.room.logic:getCurrentEvent():findParent(GameEvent.UseCard, true)
  return card_event and card_event.joy__shunshi_armor
end,
on_refresh = function(self, event, target, player, data)
  local room = player.room
  for _, p in ipairs(room.alive_players) do
    room:removePlayerMark(p, fk.MarkArmorNullified)
  end
end,
}
yise:addRelatedSkill(yise_delay)
shunshi:addRelatedSkill(shunshi_delay)
shunshi:addRelatedSkill(shunshi_targetmod)
shunshi:addRelatedSkill(shunshi_maxcards)
shunshi:addRelatedSkill(shunshi_armor)
dufuren:addSkill(yise)
dufuren:addSkill(shunshi)
Fk:loadTranslationTable{
  ["joy__dufuren"] = "杜夫人",
  ["#joy__dufuren"] = "沛王太妃",

  ["joy__yise"] = "异色",
  [":joy__yise"] = "锁定技；当其他角色获得你的牌后，若此牌为：红色，你可以摸一张牌或令其回复1点体力；黑色，你可以令其下次受到【杀】造成的伤害时，此伤害+1。",
  ["joy__shunshi"] = "顺世",
  [":joy__shunshi"] = "准备阶段或当你于回合外受到伤害后，你可以交给一名其他角色一张牌，然后你获得以下效果：下个摸牌阶段多摸一张牌、"..
  "下个出牌阶段使用的【杀】次数上限+1且无视防具、下个弃牌阶段手牌上限+1。",
  ["#joy__yise-invoke1"] = "异色：你可以选择摸一张牌或令 %dest 回复1点体力",
  ["#joy__yise-invoke3"] = "异色：你可以令 %dest 下次受到【杀】造成的伤害时，伤害+1",
  ["joy__yiseDrawCard"] = "你摸一张牌",
  ["joy__yiseCover"] = "令其回复1点体力",
  ["joy__yisecancel"] = "取消",

  ["#joy__shunshi-cost"] = "顺世：你可以交给一名其他角色一张牌，然后你下个对应阶段获得对应效果",
  ["#joy__yise_delay"] = "异色",
  ["#joy__shunshi_delay"] = "顺世",
  ["@joy__yise"] = "异色",
  ["@joy__shunshi_drawcards"] = "摸牌阶段",
  ["@joy__shunshi_slash"] = "出牌阶段",
  ["@joy__shunshi_maxcard"] = "弃牌阶段",

}

local zhangchangpu = General(extension, "joy__zhangchangpu", "wei", 3, 3, General.Female)
Fk:addPoxiMethod{
  name = "joy__yanjiao_count",
  card_filter = function(to_select, selected,data,extra_data)
    local n = Fk:getCardById(to_select).number
    for _, id in ipairs(selected) do
      n = n + Fk:getCardById(id).number
    end
    return n <= extra_data//2
  end,
  feasible = function(selected)
    return #selected > 0
  end,
  prompt = function ()
    return Fk:translate("#joy__yanjiao-choose")
  end
}
local yanjiao = fk.CreateActiveSkill{
  name = "joy__yanjiao",
  anim_type = "support",
  card_num = 0,
  target_num = 1,
  prompt = "#joy__yanjiao",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected, selected_cards)
    return #selected == 0 
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local n = 3 + player:getMark("@joy__yanjiao")
    room:setPlayerMark(player, "@joy__yanjiao", 0)
    local cards = room:getNCards(n)
    room:moveCards({
      ids = cards,
      toArea = Card.Processing,
      moveReason = fk.ReasonJustMove,
      skillName = self.name,
    })
    local m = 0
    local i = 1
    for _, id in ipairs(cards) do
      local card = Fk:getCardById(id)
      m = m + Fk:getCardById(id).number
      room:addCardMark(card,"joy_yj-phase",m)
    end
    local get = room:askForPoxi(target, "joy__yanjiao_count", {{ self.name, cards}}, m, true)
    if #get > 0 then
      local dummy = Fk:cloneCard("dilu")
      dummy:addSubcards(get)
      room:obtainCard(target.id, dummy, true, fk.ReasonPrey)
    end
    cards = table.filter(cards, function(id) return room:getCardArea(id) == Card.Processing end)
    if target ~= player and not player.dead and #cards > 0 then
      local dummy2 = Fk:cloneCard("dilu")
      dummy2:addSubcards(cards)
      room:obtainCard(player.id, dummy2, true, fk.ReasonPrey)
    elseif target == player and #cards > 0 then
        room:moveCards({
          ids = cards,
          toArea = Card.DiscardPile,
          moveReason = fk.ReasonPutIntoDiscardPile,
        })
    end
  end,
}
local xingshen = fk.CreateTriggerSkill{
  name = "joy__xingshen",
  anim_type = "masochism",
  events = {fk.Damaged},
  on_use = function(self, event, target, player, data)
    local room = player.room
    if table.every(room.alive_players, function(p) return p:getHandcardNum() >= player:getHandcardNum() end) then
      player:drawCards(2, self.name)
    else
      player:drawCards(1, self.name)
    end
    if player.dead or player:getMark("@joy__yanjiao") > 5 then return end
    if table.every(room.alive_players, function(p) return p.hp >= player.hp end) then
      room:addPlayerMark(player, "@joy__yanjiao", player:getMark("@joy__yanjiao") > 3 and 1 or 2)
    else
      room:addPlayerMark(player, "@joy__yanjiao", 1)
    end
  end,
}
zhangchangpu:addSkill(yanjiao)
zhangchangpu:addSkill(xingshen)
Fk:loadTranslationTable{
  ["joy__zhangchangpu"] = "张昌蒲",
  ["#joy__zhangchangpu"] = "矜严明训",

  ["joy__yanjiao"] = "严教",
  [":joy__yanjiao"] = "出牌阶段限一次，你可以选择一名角色并亮出牌堆顶的三张牌，该角色选择并获得点数之和小于等于总点数一半的牌（至少获得一张），"..
  " 若〖严教〗目标不为你，你获得剩余的牌；若〖严教〗目标为你，则弃置剩余的牌。",
  ["joy__xingshen"] = "省身",
  [":joy__xingshen"] = "当你受到伤害后，你可以摸一张牌并令下一次发动〖严教〗亮出的牌数+1。若你的手牌数为全场最少，则改为摸两张牌；"..
  "若你的体力值为全场最少，则下一次发动〖严教〗亮出的牌数改为+2（加值总数至多为5）。",
  ["#joy__yanjiao"]= "严教：选择一名角色发动“严教”",
  ["#joy__yanjiao-choose"] = "严教：选择获得点数和小于总点数一半的牌",
  ["joy__yanjiao_count"] = "严教",
  ["@joy__yanjiao"] = "严教",
  
  ["$joy__yanjiao1"] = " ",
  ["$joy__yanjiao2"] = " ",
  ["$joy__xingshen1"] = " ",
  ["$joy__xingshen2"] = " ",
  ["~joy__zhangchangpu"] = " ",
}

local wenqin = General(extension, "joy__wenqin", "wei", 4)
wenqin:addSkill("guangao")
wenqin:addSkill("huiqi")
wenqin:addRelatedSkill("xieju")
Fk:loadTranslationTable{
  ["joy__wenqin"] = "文钦",
  ["#joy__wenqin"] = "困兽鸱张",
}

local lijue = General(extension, "joy__lijue", "qun", 5, 6)
lijue:addSkill("langxi")
lijue:addSkill("yisuan")
Fk:loadTranslationTable{
  ["joy__lijue"] = "李傕",
  ["#joy__lijue"] = "恐怖羊袭",
}

local liangxing = General(extension, "joy__liangxing", "qun", 4)
local lulue = fk.CreateTriggerSkill{
  name = "joy__lulue",
  anim_type = "offensive",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Play
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = table.map(table.filter(room:getOtherPlayers(player), function(p)
      return (p:getHandcardNum() <= #player.player_cards[Player.Hand] and not p:isKongcheng()) end), Util.IdMapper)
    if #targets == 0 then return end
    local to = room:askForChoosePlayers(player, targets, 1, 1, "#joy__lulue-choose", self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
    return false
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    local choice = room:askForChoice(to, {"lulue_give", "lulue_slash"}, self.name, "#lulue-choice:"..player.id)
    if choice == "lulue_give" then
      local dummy = Fk:cloneCard("dilu")
      dummy:addSubcards(to:getCardIds(Player.Hand))
      room:obtainCard(player.id, dummy, false, fk.ReasonGive)
      player:turnOver()
    else
      to:turnOver()
      room:useVirtualCard("slash", nil, to, player, self.name, true)
    end
  end,
}
liangxing:addSkill(lulue)
liangxing:addSkill("zhuixi")
Fk:loadTranslationTable{
  ["joy__liangxing"] = "梁兴",
  ["#joy__liangxing"] = "凶豺掠豹",

  ["joy__lulue"] = "掳掠",
  [":joy__lulue"] = "出牌阶段开始时，你可以令一名有手牌且手牌数小于等于你的其他角色选择一项：1.将所有手牌交给你，然后你翻面；2.翻面，然后视为对你使用一张【杀】。",
  ["#joy__lulue-choose"] = "掳掠：你可以令一名有手牌且手牌数小于等于你的其他角色选择一项",
}



local joy__zhaoxiang = General(extension, "joy__zhaoxiang", "shu", 4, 4, General.Female)
local joy__fuhan = fk.CreateTriggerSkill{
  name = "joy__fuhan",
  events = {fk.TurnStart},
  frequency = Skill.Limited,
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player:getMark("@meiying") > 0 and
      player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#joy__fuhan-invoke")
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = player:getMark("@meiying")
    room:setPlayerMark(player, "@meiying", 0)
    player:drawCards(n, self.name)
    if player.dead then return end
    local generals = {}
    local gens = {"joy__zhaoxiang"}
    for _, p in ipairs(room.alive_players) do
      table.insertIfNeed(gens,p.general)
      if p.deputyGeneral ~= "" then
        table.insertIfNeed(gens,p.deputyGeneral)
      end
    end
    for _, general in pairs(Fk.generals) do
      if general.package.extensionName == "joy" and general.kingdom == "shu" and not table.contains(gens,general.name) then
        table.insert(generals, general.name)
      end
    end
    if #generals > 0 then 
    generals = table.random(generals, math.max(4, #room.alive_players))

    local skills = {}
    local choices = {}
    for _, general_name in ipairs(generals) do
      local general = Fk.generals[general_name]
      local g_skills = {}
      for _, skill in ipairs(general.skills) do
        if not (table.contains({Skill.Limited, Skill.Wake, Skill.Quest}, skill.frequency) or skill.lordSkill) and
        (#skill.attachedKingdom == 0 or (table.contains(skill.attachedKingdom, "shu") and player.kingdom == "shu")) then
          table.insertIfNeed(g_skills, skill.name)
        end
      end
      for _, s_name in ipairs(general.other_skills) do
        local skill = Fk.skills[s_name]
        if not (table.contains({Skill.Limited, Skill.Wake, Skill.Quest}, skill.frequency) or skill.lordSkill) and
        (#skill.attachedKingdom == 0 or (table.contains(skill.attachedKingdom, "shu") and player.kingdom == "shu")) then
          table.insertIfNeed(g_skills, skill.name)
        end
      end
      table.insertIfNeed(skills, g_skills)
      if #choices == 0 and #g_skills > 0 then
        choices = {g_skills[1]}
      end
    end
    if #choices > 0 then
      local result = player.room:askForCustomDialog(player, self.name,
      "packages/tenyear/qml/ChooseGeneralSkillsBox.qml", {
        generals, skills, 1, 2, "#joy__fuhan-choice", false
      })
      if result ~= "" then
        choices = json.decode(result)
      end
      room:handleAddLoseSkills(player, table.concat(choices, "|"), nil)
    end
    end
    if not player.dead and player:isWounded() and
    table.every(room.alive_players, function(p) return p.hp >= player.hp end) then
      room:recover({
        who = player,
        num = 1,
        recoverBy = player,
        skillName = self.name
      })
    end
  end,
}
joy__zhaoxiang:addSkill("ty__fanghun")
joy__zhaoxiang:addSkill(joy__fuhan)
Fk:loadTranslationTable{
  ["joy__zhaoxiang"] = "赵襄",
  ["#joy__zhaoxiang"] = "拾梅鹊影",

  ["joy__fuhan"] = "扶汉",
  [":joy__fuhan"] = "限定技，回合开始时，若你有“梅影”标记，你可以移去所有“梅影”标记并摸等量的牌，然后从X张（X为存活人数且至少为4）蜀势力"..
  "武将牌中选择并获得至多两个技能（限定技、觉醒技、主公技除外）。若此时你是体力值最低的角色，你回复1点体力。",
  ["#joy__fuhan-invoke"] = "扶汉：你可以移去“梅影”标记，获得两个蜀势力武将的技能！",
  ["#joy__fuhan-choice"] = "扶汉：选择你要获得的至多2个技能",
}

local yangwan = General(extension, "joy__yangwan", "shu", 3, 3, General.Female)
local youyan = fk.CreateActiveSkill{
  name = "joy__youyan",
  anim_type = "control",
  min_card_num = 1,
  prompt = "#joy__youyan",
  can_use = function(self, player)
    return not player:isKongcheng() and player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = function(self, to_select, selected)
    return Fk:currentRoom():getCardArea(to_select) ~= Card.PlayerEquip
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    player.room:throwCard(effect.cards,self.name,player,player)
  end,
}
local youyan_trigger = fk.CreateTriggerSkill{
  name = "#joy__youyan__trigger",
  anim_type = "drawcard",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and (player.phase == Player.Play or player.phase == Player.Discard) and
      player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 then
      local suits = {"spade", "club", "heart", "diamond"}
      local can_invoked = false
      for _, move in ipairs(data) do
        if move.toArea == Card.DiscardPile and move.moveReason ~= fk.ReasonUse and move.moveReason ~= fk.ReasonResonpse then
          if move.from == player.id then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                table.removeOne(suits, Fk:getCardById(info.cardId):getSuitString())
                can_invoked = true
              end
            end
          else
            local room = player.room
            local parentPindianEvent = player.room.logic:getCurrentEvent():findParent(GameEvent.Pindian, true)
            if parentPindianEvent then
              local pindianData = parentPindianEvent.data[1]
              if pindianData.from == player then
                local leftFromCardIds = room:getSubcardsByRule(pindianData.fromCard)
                for _, info in ipairs(move.moveInfo) do
                  if info.fromArea == Card.Processing and table.contains(leftFromCardIds, info.cardId) then
                    table.removeOne(suits, Fk:getCardById(info.cardId):getSuitString())
                    can_invoked = true
                  end
                end
              end
              for toId, result in pairs(pindianData.results) do
                if player.id == toId then
                  local leftToCardIds = room:getSubcardsByRule(result.toCard)
                  for _, info in ipairs(move.moveInfo) do
                    if info.fromArea == Card.Processing and table.contains(leftToCardIds, info.cardId) then
                      table.removeOne(suits, Fk:getCardById(info.cardId):getSuitString())
                      can_invoked = true
                    end
                  end
                end
              end
            end
          end
        end
      end
      if can_invoked and #suits > 0 then
        self.cost_data = suits
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local suits = self.cost_data
    local cards = {}
    while #suits > 0 do
      local pattern = table.random(suits)
      table.removeOne(suits, pattern)
      table.insertTable(cards, room:getCardsFromPileByRule(".|.|"..pattern))
    end
    if #cards > 0 then
      room:moveCards({
        ids = cards,
        to = player.id,
        toArea = Card.PlayerHand,
        moveReason = fk.ReasonJustMove,
        proposer = player.id,
        skillName = self.name,
      })
    end
  end,
}
local zhuihuan = fk.CreateTriggerSkill{
  name = "joy__zhuihuan",
  anim_type = "defensive",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Finish
  end,
  on_cost = function(self, event, target, player, data)
    local to = player.room:askForChoosePlayers(player, table.map(player.room.alive_players, Util.IdMapper), 1, 1, "#joy__zhuihuan-choose", self.name, true, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    player.room:addPlayerMark(player.room:getPlayerById(self.cost_data), self.name, 1)
  end,
}
local zhuihuan_delay = fk.CreateTriggerSkill{
  name = "#joy__zhuihuan_delay",
  anim_type = "offensive",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player.phase == Player.Start and player:getMark("joy__zhuihuan") ~= 0
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, "joy__zhuihuan", 0)
    local mark = player:getTableMark( "joy__zhuihuan_record")
    local targets = table.filter(room:getAlivePlayers(), function (p)
      return table.contains(mark, p.id)
    end)
    room:setPlayerMark(player, "joy__zhuihuan_record", 0)
    for _, p in ipairs(targets) do
      if player.dead then break end
      if not p.dead then
        if p.hp > player.hp then
          room:damage({
            from = player,
            to = p,
            damage = 2,
            damageType = fk.NormalDamage,
            skillName = "joy__zhuihuan"
          })
        else
          local cards = table.filter(p:getCardIds(Player.Hand), function (id)
            return not p:prohibitDiscard(Fk:getCardById(id))
          end)
          cards = table.random(cards, 2)
          if #cards > 0 then
            room:throwCard(cards, "joy__zhuihuan", p, p)
          end
        end
      end
    end
  end,

  refresh_events = {fk.Damaged},
  can_refresh = function(self, event, target, player, data)
    return player == target and player:getMark("joy__zhuihuan") ~= 0 and data.from
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getTableMark( "joy__zhuihuan_record")
    table.insert(mark, data.from.id)
    room:setPlayerMark(player, "joy__zhuihuan_record", mark)
  end,
}
youyan:addRelatedSkill(youyan_trigger)
zhuihuan:addRelatedSkill(zhuihuan_delay)
yangwan:addSkill(youyan)
yangwan:addSkill(zhuihuan)
Fk:loadTranslationTable{
  ["joy__yangwan"] = "杨婉",
  ["#joy__yangwan"] = "融沫之鲡",

  ["joy__youyan"] = "诱言",
  [":joy__youyan"] = "①出牌阶段限一次，你可以弃置任意张手牌<br>②你的回合内，当你的牌因使用或打出之外的方式进入弃牌堆后，你可以从牌堆中获得本次弃牌中没有的花色的牌各一张（出牌阶段、弃牌阶段各限一次）。",
  ["joy__zhuihuan"] = "追还",
  [":joy__zhuihuan"] = "结束阶段，你可以秘密选择一名角色。直到该角色的下个准备阶段，此期间内对其造成过伤害的角色："..
  "若体力值大于该角色，则受到其造成的2点伤害；若体力值小于等于该角色，则随机弃置两张手牌。",
  ["#joy__zhuihuan-choose"] = "追还：选择一名角色，直到其准备阶段，对此期间对其造成过伤害的角色造成伤害或弃牌",
  ["#joy__zhuihuan_delay"] = "追还",
  ["#joy__youyan__trigger"] = "诱言",
  ["#joy__youyan"] = "诱言：出牌阶段限一次，你可以弃置任意张手牌",

  ["$joy__youyan1"] = "诱言者，为人所不齿。",
  ["$joy__youyan2"] = "诱言之弊，不可不慎。",
  ["$joy__zhuihuan1"] = "伤人者，追而还之！",
  ["$joy__zhuihuan2"] = "追而还击，皆为因果。",
  ["~joy__yangwan"] = "遇人不淑……",
}

local tangji = General(extension, "joy__tangji", "qun", 3, 3, General.Female)
local joy__kangge = fk.CreateTriggerSkill{
  name = "joy__kangge",
  events = {fk.TurnStart, fk.AfterCardsMove, fk.EnterDying},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.TurnStart then
        return target == player
      elseif event == fk.AfterCardsMove then
        if player:getMark("joy__kangge_draw-turn") < 3 then
          local n = 0
          for _, move in ipairs(data) do
            if move.to and move.toArea == Card.PlayerHand and player.room:getPlayerById(move.to):getMark("@@joy__kangge") > 0
            and player.room:getPlayerById(move.to).phase == Player.NotActive then
              n = n + #move.moveInfo
            end
          end
          if n > 0 then
            self.cost_data = n
            return true
          end
        end
      else
        return target.dying and target:getMark("@@joy__kangge") > 0 and player:getMark("joy__kangge_help-round") == 0
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.EnterDying then
      return player.room:askForSkillInvoke(player, self.name, nil, "#joy__kangge-invoke::"..target.id)
    end
    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(self.name)
    if event == fk.TurnStart then
      room:notifySkillInvoked(player, self.name, "special")
      local targets = table.map(room:getOtherPlayers(player), Util.IdMapper)
      if #targets == 0 then return end
      for _, p in ipairs(room:getOtherPlayers(player)) do
        if p:getMark("@@joy__kangge") > 0 then
          room:setPlayerMark(p, "@@joy__kangge", 0)
        end
      end
      local tos = room:askForChoosePlayers(player, targets, 1, 1, "#joy__kangge-choose", self.name, false)
      room:setPlayerMark(room:getPlayerById(tos[1]), "@@joy__kangge", 1)
    elseif event == fk.AfterCardsMove then
      room:notifySkillInvoked(player, self.name, "drawcard")
      local n = math.min(self.cost_data, 3 - player:getMark("joy__kangge_draw-turn"))
      room:addPlayerMark(player, "joy__kangge_draw-turn", n)
      player:drawCards(n, self.name)
    else
      room:notifySkillInvoked(player, "joy__kangge", "support")
      room:doIndicate(player.id, {target.id})
      room:setPlayerMark(player, "joy__kangge_help-round", 1)
      room:recover({
        who = target,
        num = 1 - target.hp,
        recoverBy = player,
        skillName = self.name,
      })
    end
  end,
}
local joy__jielie = fk.CreateTriggerSkill{
  name = "joy__jielie",
  anim_type = "defensive",
  events = {fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#joy__jielie-invoke")
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = table.filter(room:getOtherPlayers(player), function(p) return p:getMark("@@joy__kangge") > 0 end)[1]
    local suit
    if to then
      local suits = {"spade", "heart", "club", "diamond"}
      local choices = table.map(suits, function(s) return "log_"..s end)
      local choice = room:askForChoice(player, choices, self.name, "#joy__jielie-choice::"..to.id..":"..data.damage)
      suit = suits[table.indexOf(choices, choice)]
      room:doIndicate(player.id, {to.id})
    end
    room:loseHp(player, 1, self.name)
    if to and not to.dead then
      local cards = room:getCardsFromPileByRule(".|.|"..suit, data.damage, "discardPile")
      if #cards > 0 then
        room:moveCards({
          ids = cards,
          to = to.id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonJustMove,
          proposer = player.id,
          skillName = self.name,
        })
      end
    end
    return true
  end,
}
tangji:addSkill(joy__kangge)
tangji:addSkill(joy__jielie)
Fk:loadTranslationTable{
  ["joy__tangji"] = "唐姬",
  ["joy__kangge"] = "抗歌",
  [":joy__kangge"] = "回合开始时，你令一名其他角色获得“抗歌”标记（若已有此标记则转移给其）：当该角色于其回合外获得手牌时，你摸等量的牌（每回合最多摸3张）；每轮限一次，当该角色进入濒死状态时，你可以令其将体力回复至1点。",
  ["joy__jielie"] = "节烈",
  [":joy__jielie"] = "当你受到伤害时，你可以防止此伤害并选择一种花色，然后你失去1点体力，令“抗歌”角色从弃牌堆中随机获得X张此花色的牌（X为伤害值）。",
  ["#joy__kangge-choose"] = "抗歌：请选择“抗歌”角色",
  ["@@joy__kangge"] = "抗歌",
  ["#joy__kangge-invoke"] = "抗歌：你可以令 %dest 回复体力至1",
  ["#joy__jielie-invoke"] = "节烈：你可以防止你受到的伤害并失去1点体力",
  ["#joy__jielie-choice"] = "节烈：选择一种花色，令“抗歌”角色 %dest 从弃牌堆获得%arg张此花色牌",
}


local yangxiu = General(extension, "joy__yangxiu", "wei", 3)
local jilei = fk.CreateTriggerSkill{
  name = "joy__jilei",
  anim_type = "masochism",
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.from and not data.from.dead
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#joy__jilei-invoke::"..data.from.id)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local choice = room:askForChoice(player, {"basic", "trick", "equip"}, self.name)
    local cards
    if choice == "basic" then
      cards = room:getCardsFromPileByRule(".|.|.|.|.|basic")
    elseif choice == "trick" then
      cards = room:getCardsFromPileByRule(".|.|.|.|.|trick")
    elseif choice == "equip" then
      cards = room:getCardsFromPileByRule(".|.|.|.|.|equip")
    end
      if #cards > 0 and not player.dead then
        local get = cards[1]
        room:obtainCard(player, get, false, fk.ReasonDraw)
      end
    local mark = data.from:getMark("@joy__jilei")
    if mark == 0 then mark = {} end
    table.insertIfNeed(mark, choice .. "_char")
    room:setPlayerMark(data.from, "@joy__jilei", mark)
  end,

  refresh_events = {fk.TurnStart},
  can_refresh = function(self, event, target, player, data)
    return target == player and player:getMark("@joy__jilei") ~= 0
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:setPlayerMark(player, "@joy__jilei", 0)
  end,
}
local jilei_prohibit = fk.CreateProhibitSkill{
  name = "#joy__jilei_prohibit",
  prohibit_use = function(self, player, card)
    local mark = player:getMark("@joy__jilei")
    if type(mark) == "table" and table.contains(mark, card:getTypeString() .. "_char") then
      local subcards = card:isVirtual() and card.subcards or {card.id}
      return #subcards > 0 and table.every(subcards, function(id)
        return table.contains(player:getCardIds(Player.Hand), id)
      end)
    end
  end,
  prohibit_response = function(self, player, card)
    local mark = player:getMark("@joy__jilei")
    if type(mark) == "table" and table.contains(mark, card:getTypeString() .. "_char") then
      local subcards = card:isVirtual() and card.subcards or {card.id}
      return #subcards > 0 and table.every(subcards, function(id)
        return table.contains(player:getCardIds(Player.Hand), id)
      end)
    end
  end,
  prohibit_discard = function(self, player, card)
    local mark = player:getMark("@joy__jilei")
    if type(mark) == "table" and table.contains(mark, card:getTypeString() .. "_char") then
      local subcards = card:isVirtual() and card.subcards or {card.id}
      return #subcards > 0 and table.every(subcards, function(id)
        return table.contains(player:getCardIds(Player.Hand), id)
      end)
    end
  end,
}
jilei:addRelatedSkill(jilei_prohibit)
yangxiu:addSkill("ty__danlao")
yangxiu:addSkill(jilei)
Fk:loadTranslationTable{
  ["joy__yangxiu"] = "杨修",
  ["#joy__yangxiu"] = "恃才放旷",

  ["joy__jilei"] = "鸡肋",
  [":joy__jilei"] = "当你受到伤害后，你可以声明一种牌的类别，然后获得一张该类别的牌，并令伤害来源不能使用、打出或弃置你声明的此类手牌直到其下回合开始。",
  ["#joy__jilei-invoke"] = "鸡肋：是否获得一张指定类别的牌，并令 %dest 不能使用、打出、弃置该类别牌直到其下回合开始？",
  ["@joy__jilei"] = "鸡肋",
}

local quyi = General(extension, "joy__quyi", "qun", 4)
local fuji = fk.CreateTriggerSkill{
  name = "joy__fuji",
  anim_type = "offensive",
  events = {fk.CardUsing},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      (data.card.trueName == "slash" or data.card:isCommonTrick()) and
      table.find(player.room:getOtherPlayers(player), function(p) return p:distanceTo(player) < 3 end)
  end,
  on_use = function(self, event, target, player, data)
    local targets = table.filter(player.room:getOtherPlayers(player), function(p) return p:distanceTo(player) <3 end)
    if #targets > 0 then
      data.disresponsiveList = data.disresponsiveList or {}
      for _, p in ipairs(targets) do
        table.insertIfNeed(data.disresponsiveList, p.id)
      end
    end
  end,
}
local fuji_mark = fk.CreateTriggerSkill{
  name = "#joy__fuji_mark",
  anim_type = "offensive",
  mute = true,
  events = {fk.Damaged},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
      return target ~= player and data.from == player and player:hasSkill(self) and not target.dead
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
      room:addPlayerMark(target, "@@joyfuji")
      room:addPlayerMark(target, MarkEnum.UncompulsoryInvalidity)
  end,
  refresh_events = { fk.TurnStart },
  can_refresh = function(self, event, target, player, data)
      return target ~= Player 
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room:getAlivePlayers()) do
      if p:getMark("@@joyfuji") > 0 then
        room:removePlayerMark(p, "@@joyfuji")
        room:removePlayerMark(p,MarkEnum.UncompulsoryInvalidity)
      end
    end
  end,
}
local jiaozi = fk.CreateTriggerSkill{
  name = "joy__jiaozi",
  anim_type = "offensive",
  events = {fk.DamageCaused},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      table.every(player.room:getOtherPlayers(player), function(p)
        return player:getHandcardNum() >= p:getHandcardNum() end)
  end,
  on_use = function(self, event, target, player, data)
    data.damage = data.damage + 1
  end,
}
fuji:addRelatedSkill(fuji_mark)
quyi:addSkill(fuji)
quyi:addSkill(jiaozi)
Fk:loadTranslationTable{
  ["joy__quyi"] = "麴义",
  ["#joy__quyi"] = "名门的骁将",

  ["joy__fuji"] = "伏骑",
  ["#joy__fuji_mark"] = "伏骑",
  [":joy__fuji"] = "锁定技，当你使用【杀】或普通锦囊牌时，你令所有至你距离为2的角色不能响应此牌。"..
  "且被你造成伤害的其他角色的非锁定技失效，其他角色的回合开始时解除",
  ["joy__jiaozi"] = "骄恣",
  [":joy__jiaozi"] = "锁定技，当你造成伤害时，若你的手牌为全场最多，则此伤害+1。",
  ["@@joyfuji"] = "伏骑",

  ["$joy__fuji1"] = " ",
  ["$joy__fuji2"] = " ",
  ["$joy__jiaozi1"] = " ",
  ["$joy__jiaozi2"] = " ",
  ["$~joy__quyi"] = " ",
}

local joy__sunhao = General(extension, "joy__sunhao", "wu", 5)
local joy__canshi = fk.CreateTriggerSkill{
  name = "joy__canshi",
  anim_type = "drawcard",
  events = {fk.DrawNCards},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and table.find(player.room.alive_players, function (p)
      return p:isWounded() or (player:hasSkill("joy__guiming") and p.kingdom == "wu" )
    end)
  end,
  on_cost = function (self, event, target, player, data)
    local n = 0
    for _, p in ipairs(player.room.alive_players) do
      if p:isWounded() or (player:hasSkill("joy__guiming") and p.kingdom == "wu" ) then
        n = n + 1
      end
    end
    if player.room:askForSkillInvoke(player, self.name, nil, "#joy__canshi-invoke:::"..n) then
      self.cost_data = n
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    data.n = data.n + self.cost_data
  end,
}
local joy__canshi_delay = fk.CreateTriggerSkill{
  name = "#joy__canshi_delay",
  anim_type = "negative",
  events = {fk.CardUsing},
  can_trigger = function(self, event, target, player, data)
    return target == player and data.card.trueName == "slash" and
      player:usedSkillTimes(joy__canshi.name) > 0 and not player:isNude()
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    player.room:askForDiscard(player, 1, 1, true, self.name, false)
  end,
}
local joy__chouhai = fk.CreateTriggerSkill{
  name = "joy__chouhai",
  anim_type = "negative",
  frequency = Skill.Compulsory,
  events ={fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player:isKongcheng() and #player:getCardIds("e") == 0 and data.card and data.card.trueName == "slash"
    
  end,
  on_use = function(self, event, target, player, data)
    data.damage = data.damage + 1
  end,
}
local guiming = fk.CreateTriggerSkill{
  name = "joy__guiming$",
  frequency = Skill.Compulsory,
}
joy__canshi:addRelatedSkill(joy__canshi_delay)
joy__sunhao:addSkill(joy__canshi)
joy__sunhao:addSkill(joy__chouhai)
joy__sunhao:addSkill(guiming)
Fk:loadTranslationTable{
  ["joy__sunhao"] = "孙皓",
  ["#joy__sunhao"] = "时日曷丧",

  ["joy__canshi"] = "残蚀",
  [":joy__canshi"] = "摸牌阶段，你可以多摸X张牌（X为已受伤的角色数），若如此做，当你于此回合内使用【杀】时，你弃置一张牌。",
  ["#joy__canshi_delay"] = "残蚀",
  ["joy__chouhai"] = "仇海",
  [":joy__chouhai"] = "锁定技，当你受到【杀】造成的伤害时，若你没有手牌和装备，此伤害+1。",
  ["#joy__canshi-invoke"] = "残蚀：你可以多摸 %arg 张牌",

  ["joy__guiming"] = "归命",
  [":joy__guiming"] = "主公技，锁定技，吴势力角色于你的回合内视为已受伤的角色。",

}

local xushao = General(extension, "joy__xushao", "qun", 4)

local pingjian_skills = {
  -- 出牌阶段
  ["play"] =
  {
  "nya__lijian","nya__guose","nya__jieyi","joyex__lijian","joyex__duanliang","joy__shenglun","joyex__qiangxi",
  "joy__jueyan","joy__huairou","joy__qice","joy__kuangbi","joy__mingjian","joy__huoxin","joy__poxi","shencai","joy__yingba","ol__xuehen",
  "joy__yanxiao","joy__xingwu","joy__guolun","joysp__juesi","joy__lihun","joy_mou__kurou","xieju","duanfa","jiezhen","joy__mingjian",
  "ty__gushe","anzhi","zhuren","jinghe","jinhui","yuanyu","joy__wengua","kurou","joy__duwu","joy__anguo","joy__god_huishi","joy__zuoxing",
  "zhanhuo","joy__jianshu","zunwei","joysp__weikui","joy__manwang","joy__jixu","joy__xiaowu","joy__channi","joy__quanji","joy__paiyi",
  "ty__zhongjian","joy__weilie","joy__yanjiao","joyex__zhiheng","joyex__jieyi","joyex__wanrong","joyex__qixi","joy__xianzhu","joy__youyan",
  "limu","joy_mou__duojing","joy_mou__luanji","joyex__qingnang","joy_mou__duanliang","joy__difa","ty_ex__wurong","joyex__changbiao","joy_mou__qingzheng","joy__chenglue","joyex__wuchang","joy__mubing","joy__diaoling","joyex__rende","joy__lusu","joy__miaoxian","joy__liaoyuan",
  "joy__miaoxian","yijiao","jouex__fanjian","jinggong","fengyan","joy__shangyi",
  --限定技，觉醒技
  "joy__wujian","nya__xianzhou","joyex__qimou","xiongluan","joy__shenfen","joy__pingxiang","ex__yongjin","mobile__limited_huishi","joy__yongbi",
  "joy__yongdi","joy_mou__zhangwu",
  },
  --受到伤害后 
  [fk.Damaged] =
  {
    --[[
    "joyex__fankui","ex__yiji","joyex__jianxiong","joy__fangzhu","joy__zhiyu","huituo","joy__jieying","joy__guixin",
    "joy__chouce","ex__jianxiong","yuqi","qianlong","lundao","joy_mou__jianxiong","joy__shunshi","joy__chengxiang",
    "wangxi","joy__jilei","joy__xingshen","ex__ganglie","joy__benyu","joy__shefu","joy__baobian","zhichi","joy__quanji","joy__jiushi",
    ]]
    "joyex__fankui","ex__yiji","joyex__jianxiong","joy__fangzhu","joy__zhiyu","huituo","joy__jieying","joy__wuhun","joy__guixin",
        "joy__chouce","ex__jianxiong","yuqi","qianlong","lundao","joy_mou__jianxiong","joy__shunshi","junlue","joy__chengxiang",
        "wangxi","joy__jilei","joy__xingshen","ex__ganglie","joy__benyu","joy__shefu","joy__baobian","zhichi","joy__xinghan",
  },
  --结束阶段
  [fk.EventPhaseStart] =
  {
    --[[
    "nya__biyue","nya__miji","joyex__biyue","ty_ex__zhenjun","joy__jujian","joy__jieying","joy__meihun","joy__shenfu","joy__benghuai",
    "mozhi","joy__youdi","joy__fujian","joy__dianhua","gongxiu","guanyue","ex__biyue","zhiyan","zhukou","fuxue","nya__luoshen",
    "zhengu","joy__zuilun","joy__yingyu","joy__guanxing","joysp__kunfen","joysp__lizhan","joy__xunxun","joy__shefu","joy__yishe","joy_mou__shipo","joy__zhuihuan",
    ]]
    "nya__biyue","nya__miji","joyex__biyue","ty_ex__zhenjun","joy__jujian","joy__jieying","joy__meihun","joy__shenfu","joy__benghuai",
        "mozhi","joy__youdi","joy__fujian","joy__dianhua","gongxiu","guanyue","ex__biyue","zhiyan","zhukou","fuxue","nya__luoshen","miji",
        "zhengu","joy__zuilun","joy__yingyu","joy__guanxing","joysp__kunfen","joysp__lizhan","joy__xunxun","joy__shefu","joy__yishe","joy_mou__shipo","joy__zhuihuan","joyex__jushou","ld__shengxi",
        --觉醒技，限定技
        "joy__wuji","joyex__qinxue",
  }
}

local getPingjianSkills = function (player, event)
  local used_skills = player:getTableMark( "joy__pingjian_used")
  local e = event and event or "play"
  return table.filter(pingjian_skills[e], function (skill_name)
    local sk = Fk.skills[skill_name]
    return sk and not table.contains(used_skills, skill_name) and not player:hasSkill(sk, true)
  end)
end

---@param player ServerPlayer
local addTYPingjianSkill = function(player, skill_name)
  local room = player.room
  local skill = Fk.skills[skill_name]
  if skill == nil or player:hasSkill(skill_name, true) then return false end
  room:handleAddLoseSkills(player, skill_name, nil)
  local skills = player:getTableMark( "joy__pingjian_skills")
  table.insertIfNeed(skills, skill_name)
  room:setPlayerMark(player, "joy__pingjian_skills", skills)
  local pingjian_skill_times = player:getTableMark( "joy__pingjian_skill_times")
  table.insert(pingjian_skill_times, {skill_name, player:usedSkillTimes(skill_name)})
  for _, s in ipairs(skill.related_skills) do
    table.insert(pingjian_skill_times, {s.name, player:usedSkillTimes(s.name)})
  end
  room:setPlayerMark(player, "joy__pingjian_skill_times", pingjian_skill_times)
end

---@param player ServerPlayer
local removeTYPingjianSkill = function(player, skill_name)
  local room = player.room
  local skill = Fk.skills[skill_name]
  if skill == nil then return false end
  room:handleAddLoseSkills(player, "-" .. skill_name, nil)
  local skills = player:getTableMark( "joy__pingjian_skills")
  table.removeOne(skills, skill_name)
  room:setPlayerMark(player, "joy__pingjian_skills", skills)
  local invoked = false
  local pingjian_skill_times = player:getTableMark( "joy__pingjian_skill_times")
  local record_copy = {}
  for _, pingjian_record in ipairs(pingjian_skill_times) do
    if #pingjian_record == 2 then
      local record_name = pingjian_record[1]
      if record_name == skill_name or not table.every(skill.related_skills, function (s)
          return s.name ~= record_name end) then
        if player:usedSkillTimes(record_name) > pingjian_record[2] then
          invoked = true
        end
      else
        table.insert(record_copy, pingjian_record)
      end
    end
  end
  room:setPlayerMark(player, "joy__pingjian_skill_times", record_copy)

  if invoked then
    local used_skills = player:getTableMark( "joy__pingjian_used")
    table.insertIfNeed(used_skills, skill_name)
    room:setPlayerMark(player, "joy__pingjian_used", used_skills)
  end
end

local joy__pingjian = fk.CreateActiveSkill{
  name = "joy__pingjian",
  prompt = "#joy__pingjian-active",
  card_num = 0,
  target_num = 0,
  card_filter = Util.FalseFunc,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local skills = getPingjianSkills(player)
    if #skills == 0 then return false end
    local choices = table.random(skills, 3)
    local skill_name = room:askForChoice(player, choices, self.name, "#joy__pingjian-choice", true)
    local phase_event = room.logic:getCurrentEvent():findParent(GameEvent.Phase)
    if phase_event ~= nil then
      addTYPingjianSkill(player, skill_name)
      phase_event:addCleaner(function()
        removeTYPingjianSkill(player, skill_name)
      end)
    end
  end,
}
local joy__pingjian_trigger = fk.CreateTriggerSkill{
  name = "#joy__pingjian_trigger",
  events = {fk.Damaged, fk.EventPhaseStart},
  main_skill = joy__pingjian,
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(joy__pingjian) or player ~= target then return false end
    if event == fk.Damaged then
      return true
    elseif event == fk.EventPhaseStart then
      return player.phase == Player.Finish
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:notifySkillInvoked(player, joy__pingjian.name)
    player:broadcastSkillInvoke(joy__pingjian.name)
    local skills = getPingjianSkills(player, event)
    if #skills == 0 then return false end
    local choices = table.random(skills, 3)
    local skill_name = room:askForChoice(player, choices, joy__pingjian.name, "#joy__pingjian-choice", true)
    local skill = Fk.skills[skill_name]
    if skill == nil then return false end
    local _skill = skill
    if not _skill:isInstanceOf(TriggerSkill) then
      _skill = table.find(_skill.related_skills, function (s)
        return s:isInstanceOf(TriggerSkill)
      end)
      if not _skill then return end
    end

    addTYPingjianSkill(player, skill_name)
    if _skill:triggerable(event, target, player, data) then
      _skill:trigger(event, target, player, data)
    end
    removeTYPingjianSkill(player, skill_name)
  end,

  refresh_events = {fk.DamageInflicted},
  can_refresh = function(self, event, target, player, data)
    return target == player and not player.faceup
  end,
  on_refresh = function(self, event, target, player, data)
    data.extra_data = data.extra_data or {}
    data.extra_data.jiushi_check = true
  end,
}
local joy__pingjian_invalidity = fk.CreateInvaliditySkill {
  name = "#joy__pingjian_invalidity",
  invalidity_func = function(self, player, skill)
    local pingjian_skill_times = player:getTableMark( "joy__pingjian_skill_times")
    return table.find(pingjian_skill_times, function (pingjian_record)
      if #pingjian_record == 2 then
        local skill_name = pingjian_record[1]
        if skill.name == skill_name or not table.every(skill.related_skills, function (s)
          return s.name ~= skill_name end) then
            return player:usedSkillTimes(skill_name) > pingjian_record[2]
        end
      end
    end)
  end
}

joy__pingjian:addRelatedSkill(joy__pingjian_trigger)
joy__pingjian:addRelatedSkill(joy__pingjian_invalidity)
xushao:addSkill(joy__pingjian)

Fk:loadTranslationTable{
  ["joy__xushao"] = "许劭",
  ["#joy__xushao"] = "识人读心",
  
  ["joy__pingjian"] = "评荐",
  ["#joy__pingjian_trigger"] = "评荐",
  [":joy__pingjian"] = "出牌阶段，或结束阶段，或当你受到伤害后，你可以从对应时机的技能池中随机抽取三个技能，"..
    "然后你选择并视为拥有其中一个技能直到时机结束（每个技能限发动一次）。",
  ["#joy__pingjian-active"] = "评荐：从三个出牌阶段的技能中选择一个学习",
  ["#joy__pingjian-choice"] = "评荐：选择要学习的技能",

  ["$joy__pingjian1"] = "我乘青舟访人间，人如江鲫逐功名。",
  ["$joy__pingjian2"] = "一言难道千秋业 一纸雅评半世人。",
  ["~joy__xushao"] = "满纸辛酸荒唐泪,君当务实莫贪名！",
}
--[[
local xushao = General(extension, "joy__xushao", "qun", 4)

---@param player ServerPlayer
local addTYPingjianSkill = function(player, skill_name)
  local room = player.room
  local skill = Fk.skills[skill_name]
  if skill == nil or player:hasSkill(skill_name, true) then return false end
  room:handleAddLoseSkills(player, skill_name, nil)
  local pingjian_skills = player:getTableMark( "joy__pingjian_skills")
  table.insertIfNeed(pingjian_skills, skill_name)
  room:setPlayerMark(player, "joy__pingjian_skills", pingjian_skills)
  local pingjian_skill_times = player:getTableMark( "joy__pingjian_skill_times")
  table.insert(pingjian_skill_times, {skill_name, player:usedSkillTimes(skill_name)})
  for _, s in ipairs(skill.related_skills) do
    table.insert(pingjian_skill_times, {s.name, player:usedSkillTimes(s.name)})
  end
  room:setPlayerMark(player, "joy__pingjian_skill_times", pingjian_skill_times)
end

---@param player ServerPlayer
local removeTYPingjianSkill = function(player, skill_name)
  local room = player.room
  local skill = Fk.skills[skill_name]
  if skill == nil then return false end
  room:handleAddLoseSkills(player, "-" .. skill_name, nil)
  local pingjian_skills = player:getTableMark( "joy__pingjian_skills")
  table.removeOne(pingjian_skills, skill_name)
  room:setPlayerMark(player, "joy__pingjian_skills", pingjian_skills)
  local invoked = false
  local pingjian_skill_times = player:getTableMark( "joy__pingjian_skill_times")
  local record_copy = {}
  for _, pingjian_record in ipairs(pingjian_skill_times) do
    if #pingjian_record == 2 then
      local record_name = pingjian_record[1]
      if record_name == skill_name or not table.every(skill.related_skills, function (s)
          return s.name ~= record_name end) then
        if player:usedSkillTimes(record_name) > pingjian_record[2] then
          invoked = true
        end
      else
        table.insert(record_copy, pingjian_record)
      end
    end
  end
  room:setPlayerMark(player, "joy__pingjian_skill_times", record_copy)

  if invoked then
    local used_skills = player:getTableMark( "joy__pingjian_used_skills")
    table.insertIfNeed(used_skills, skill_name)
    room:setPlayerMark(player, "joy__pingjian_used_skills", used_skills)
  end
end

local ty__pingjian = fk.CreateActiveSkill{
  name = "joy__pingjian",
  prompt = "#joy__pingjian-active",
  card_num = 0,
  target_num = 0,
  can_use = function(self, player)
    return player:getMark("joy__pingjian-phase") == 0
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local used_skills = player:getTableMark( "joy__pingjian_used_skills")
    local skills = table.filter({
      "nya__lijian","nya__guose","nya__jieyi","joy__daoyao","joy__tuantu","joyex__lijian","joyex__duanliang","joy__shenglun","joyex__qiangxi",
      "joy__jueyan","joy__huairou","joy__qice","joy__kuangbi","joy__mingjian","joy__huoxin","joy__poxi","shencai","joy__yingba","ol__xuehen",
      "joy__yanxiao","joy__xingwu","joy__guolun","joysp__juesi","joy__lihun","joy_mou__kurou","xieju","duanfa","jiezhen","joy__mingjian",
      "ty__gushe","anzhi","zhuren","jinghe","jinhui","yuanyu","joy__wengua","kurou","joy__duwu","joy__anguo","joy__god_huishi","joy__zuoxing",
      "zhanhuo","joy__jianshu","zunwei","joysp__weikui","joy__manwang","joy__jixu","joy__xiaowu","joy__channi","joy__quanji","joy__paiyi",
      "ty__zhongjian","joy__weilie","joy__yanjiao","joyex__zhiheng","joyex__jieyi","joyex__wanrong","joyex__qixi","joy__xianzhu","joy__youyan",
      "limu","joy_mou__duojing","joy_mou__luanji","joyex__qingnang","joy_mou__duanliang","joy__difa","ty_ex__wurong","joyex__changbiao","joy_mou__qingzheng","joy__chenglue","joyex__wuchang",
      --限定技，觉醒技
      "joy__wujian","nya__xianzhou","joyex__qimou","xiongluan","joy__shenfen","joy__pingxiang","ex__yongjin","mobile__limited_huishi","joy__yongbi",
      "joy__yongdi","joy_mou__zhangwu",
    }, function (skill_name)
      return not table.contains(used_skills, skill_name) and not player:hasSkill(skill_name, true)
    end)
    if #skills == 0 then return false end
    local choices = table.random(skills, 3)
    local skill_name = room:askForChoice(player, choices, self.name, "#joy__pingjian-choice", true)
    room:setPlayerMark(player,"joy__pingjian-phase",1)
    local phase_event = room.logic:getCurrentEvent():findParent(GameEvent.Phase)
    if phase_event ~= nil then
      addTYPingjianSkill(player, skill_name)
      phase_event:addCleaner(function()
        removeTYPingjianSkill(player, skill_name)
      end)
    end
  end,
}
local ty__pingjian_trigger = fk.CreateTriggerSkill{
  name = "#joy__pingjian_trigger",
  events = {fk.Damaged, fk.EventPhaseStart},
  main_skill = ty__pingjian,
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(ty__pingjian.name) or player ~= target then return false end
    if event == fk.Damaged then
      return true
    elseif event == fk.EventPhaseStart then
      return player.phase == Player.Finish
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:notifySkillInvoked(player, ty__pingjian.name)
    player:broadcastSkillInvoke(ty__pingjian.name)
    local used_skills = player:getTableMark( "joy__pingjian_used_skills")
    local skills = {}
    if event == fk.Damaged then
      skills = table.filter({
        "joyex__fankui","ex__yiji","joyex__jianxiong","joy__fangzhu","joy__zhiyu","huituo","joy__jieying","joy__wuhun","joy__guixin",
        "joy__chouce","ex__jianxiong","yuqi","qianlong","lundao","joy_mou__jianxiong","joy__shunshi","junlue","joy__chengxiang",
        "wangxi","joy__jilei","joy__xingshen","ex__ganglie","joy__benyu","joy__shefu","joy__baobian","zhichi",
      }, function (skill_name)
        return not table.contains(used_skills, skill_name) and not player:hasSkill(skill_name, true)
      end)
    elseif event == fk.EventPhaseStart then
      skills = table.filter({
        "nya__biyue","nya__miji","joyex__biyue","ty_ex__zhenjun","joy__jujian","joy__jieying","joy__meihun","joy__shenfu","joy__benghuai",
        "mozhi","joy__youdi","joy__fujian","joy__dianhua","gongxiu","guanyue","ex__biyue","zhiyan","zhukou","fuxue","nya__luoshen","miji",
        "zhengu","joy__zuilun","joy__yingyu","joy__guanxing","joysp__kunfen","joysp__lizhan","joy__xunxun","joy__shefu","joy__yishe","joy_mou__shipo","joy__zhuihuan",
        --觉醒技，限定技
        "joy__wuji","joyex__qinxue",
      }, function (skill_name)
        return not table.contains(used_skills, skill_name) and not player:hasSkill(skill_name, true)
      end)
    end
    if #skills == 0 then return false end
    local choices = table.random(skills, 3)
    local skill_name = room:askForChoice(player, choices, ty__pingjian.name, "#joy__pingjian-choice", true)
    local skill = Fk.skills[skill_name]
    if skill == nil then return false end

    addTYPingjianSkill(player, skill_name)
    if skill:triggerable(event, target, player, data) then
      skill:trigger(event, target, player, data)
    end
    removeTYPingjianSkill(player, skill_name)
  end,
}
local ty__pingjian_invalidity = fk.CreateInvaliditySkill {
  name = "#joy__pingjian_invalidity",
  invalidity_func = function(self, player, skill)
    local pingjian_skill_times = player:getTableMark( "joy__pingjian_skill_times")
    return table.find(pingjian_skill_times, function (pingjian_record)
      if #pingjian_record == 2 then
        local skill_name = pingjian_record[1]
        if skill.name == skill_name or not table.every(skill.related_skills, function (s)
          return s.name ~= skill_name end) then
            return player:usedSkillTimes(skill_name) > pingjian_record[2]
        end
      end
    end)
  end
}

ty__pingjian:addRelatedSkill(ty__pingjian_trigger)
ty__pingjian:addRelatedSkill(ty__pingjian_invalidity)
xushao:addSkill(ty__pingjian)

Fk:loadTranslationTable{
  ["joy__xushao"] = "许劭",
  ["#joy__xushao"] = "食人毒心",

  ["joy__pingjian"] = "评荐",
  ["#joy__pingjian_trigger"] = "评荐",
  [":joy__pingjian"] = "出牌阶段，或结束阶段，或当你受到伤害后，你可以从对应时机的技能池中随机抽取三个技能，"..
    "然后你选择并视为拥有其中一个技能直到时机结束（每个技能限发动一次）。"..
    '<br /><font color="red">（村：欢杀包特色，只会获得欢杀池内武将的技能，没说不能拿的技能就是能拿）</font>',
  ["#joy__pingjian-active"] = "发动 评荐，从三个出牌阶段的技能中选择一个学习",
  ["#joy__pingjian-choice"] = "评荐：选择要学习的技能",

  ["$joy__pingjian1"] = "我乘青舟访人间，人如江鲫逐功名。",
  ["$joy__pingjian2"] = "一言难道千秋业 一纸雅评半世人。",
  ["~joy__xushao"] = "满纸辛酸荒唐泪,君当务实莫贪名！",

}]]

local joy__guansuo = General(extension, "joy__guansuo", "shu", 4)
local joy__zhengnan = fk.CreateTriggerSkill{
  name = "joy__zhengnan",
  anim_type = "drawcard",
  events = {fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and (player:getMark(self.name) == 0 or not table.contains(player:getMark(self.name), target.id))
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getMark(self.name)
    local n = 0
      if target == player and player:hasSkill(self) then
        n = 1
      end
    if mark == 0 then mark = {} end
    table.insert(mark, target.id)
    room:setPlayerMark(player, self.name, mark)
    if player:isWounded() then
      room:recover({
        who = player,
        num = 1+n,
        recoverBy = player,
        skillName = self.name
      })
    end
    local choices = {"joy__wusheng", "joyex__dangxian", "ty_ex__zhiman"}
    for i = 3, 1, -1 do
      if player:hasSkill(choices[i], true) then
        table.removeOne(choices, choices[i])
      end
    end
    if #choices > 0 then
      player:drawCards(1+n, self.name)
      local choice = room:askForChoice(player, choices, self.name, "#joy__zhengnan-choice", true)
      room:handleAddLoseSkills(player, choice, nil)
    else
      player:drawCards(3+n, self.name)
    end
  end,
}
local joy__xiefang = fk.CreateDistanceSkill{
  name = "joy__xiefang",
  correct_func = function(self, from, to)
    if from:hasSkill(self) then
      local n = 0
      for _, p in ipairs(Fk:currentRoom().alive_players) do
        if p.gender == General.Female then
          n = n + 1
        end
      end
      local m = math.max(n,1)
      return -m
    end
    return 0
  end,
}
local joy__xiefang_maxcards = fk.CreateMaxCardsSkill{
  name = "#joy__xiefang_maxcards",
  correct_func = function(self, player)
    if player:hasSkill(self) then
      local n = 0
      for _, p in ipairs(Fk:currentRoom().alive_players) do
        if p.gender == General.Female then
          n = n + 1
        end
      end
      local m = math.max(n,1)
      return m
    end
    return 0
  end,
}


local joy__wusheng = fk.CreateTriggerSkill{
  name = "joy__wusheng",
  anim_type = "offensive",
  pattern = "slash",
  events = {fk.TurnStart, fk.AfterCardUseDeclared},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      return (event == fk.TurnStart) or (data.card.trueName == "slash" and data.card.color == Card.Red)
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      room:notifySkillInvoked(player, "joy__wusheng", "drawcard")
      local ids = room:getCardsFromPileByRule("slash|.|heart,diamond", 1, "allPiles")
      if #ids > 0 then
        room:obtainCard(player, ids[1], false, fk.ReasonPrey)
      end
    else
      room:notifySkillInvoked(player, "joy__wusheng", "offensive")
      data.additionalDamage = (data.additionalDamage or 0) + 1
    end
  end,
}
joy__xiefang:addRelatedSkill(joy__xiefang_maxcards)
joy__guansuo:addSkill(joy__zhengnan)
joy__guansuo:addSkill(joy__xiefang)
joy__guansuo:addRelatedSkill(joy__wusheng)
joy__guansuo:addRelatedSkill("joyex__dangxian")
joy__guansuo:addRelatedSkill("ty_ex__zhiman")
Fk:loadTranslationTable{
  ["joy__guansuo"] = "关索",
  ["#joy__guansuo"] = "倜傥孑侠",

  ["joy__zhengnan"] = "征南",
  [":joy__zhengnan"] = "每名角色限一次，当一名角色进入濒死状态时，你可以回复1点体力，然后摸一张牌并选择获得下列技能中的一个："..
  "〖武圣〗，〖当先〗和〖制蛮〗（若技能均已获得，则改为摸三张牌），若自己濒死，则回复体力数和摸牌数+1。",
  ["joy__xiefang"] = "撷芳",
  [":joy__xiefang"] = "锁定技，你计算与其他角色的距离-X,你的手牌上限+X（X为全场女性角色数且至少为1）。",
  ["#joy__zhengnan-choice"] = "征南：选择获得的技能",
  ["joy__wusheng"] = "武圣",
  [":joy__wusheng"] = "回合开始时，你获得一张红色【杀】，你的红色【杀】伤害+1。",

  ["$joy__wusheng_joy__guansuo"] = "我敬佩你的勇气。",
  ["$joyex__dangxian_joy__guansuo"] = "时时居先，方可快人一步。",
  ["$ty_ex__zhiman_joy__guansuo"] = "败军之将，自当纳贡！",
}

local joy__huangchengyan = General(extension, "joy__huangchengyan", "qun", 3)
local joy__zecai = fk.CreateTriggerSkill{
  name = "joy__zecai",
  frequency = Skill.Limited,
  events = {fk.RoundEnd},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryGame) < 1
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local player_table = {}
    room.logic:getEventsOfScope(GameEvent.UseCard, 1, function (e)
      local use = e.data[1]
      if use.card.type == Card.TypeTrick then
        local from = use.from
        player_table[from] = (player_table[from] or 0) + 1
      end
    end, Player.HistoryRound)
    local max_time, max_pid = 0, nil
    for pid, time in pairs(player_table) do
      if time > max_time then
        max_pid, max_time = pid, time
      elseif time == max_time then
        max_pid = 0
      end
    end
    local max_p = nil
    if max_pid ~= 0 then
      max_p = room:getPlayerById(max_pid)
    end
    if max_p and not max_p.dead then
      room:setPlayerMark(max_p, "@@joy__zecai_extra", 1)
    end
    local to = room:askForChoosePlayers(player, table.map(room.alive_players,Util.IdMapper), 1, 1, "#joy__zecai-choose", self.name, true)
    if max_p and not max_p.dead then
      room:setPlayerMark(max_p, "@@joy__zecai_extra", 0)
    end
    if #to > 0 then
      self.cost_data = {to[1], max_pid}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local tar = room:getPlayerById(self.cost_data[1])
    if not tar:hasSkill("joyex__jizhi", true) then
      room:addPlayerMark(tar, "joy__zecai_tmpjizhi")
      room:handleAddLoseSkills(tar, "joyex__jizhi", nil, true, false)
    end
    if self.cost_data[1] == self.cost_data[2] then
      tar:gainAnExtraTurn()
    end
  end,

  refresh_events = {fk.RoundEnd},
  can_refresh = function(self, event, target, player, data)
    return player:getMark("joy__zecai_tmpjizhi") > 0
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:handleAddLoseSkills(player, "-joyex__jizhi", nil, true, false)
  end,
}
joy__huangchengyan:addSkill("jiezhen")
joy__huangchengyan:addSkill(joy__zecai)
joy__huangchengyan:addSkill("yinshih")
Fk:loadTranslationTable{
  ["joy__huangchengyan"] = "黄承彦",
  ["#joy__huangchengyan"] = "捧月共明",
  
  ["joy__zecai"] = "择才",
  [":joy__zecai"] = "限定技，一轮结束时，你可令一名角色获得〖集智〗直到下一轮结束，然后若其是本轮使用锦囊牌数唯一最多的角色，其执行一个额外的回合。",

  ["#joy__zecai-choose"] = "你可以发动择才，令一名角色获得〖集智〗直到下轮结束",
  ["@@joy__zecai_extra"] = "择才 额外回合",

  ["$joy__zecai1"] = "诸葛良才，可为我佳婿。",
  ["$joy__zecai2"] = "梧桐亭亭，必引凤而栖。",
}


local wanglang = General(extension, "joy__wanglang", "wei", 3)
wanglang:addSkill("ty__gushe")
wanglang:addSkill("ty__jici")
Fk:loadTranslationTable{
  ["joy__wanglang"] = "王朗",
  ["#joy__wanglang"] = "凤鹛",
}

local luotong = General(extension, "joy__luotong", "wu", 3)
luotong:addSkill("renzheng")
luotong:addSkill("jinjian")
Fk:loadTranslationTable{
  ["joy__luotong"] = "骆统",
  ["#joy__luotong"] = "蹇谔匪躬",
}

local caomao = General(extension, "joy__caomao", "wei", 3, 4)
caomao:addSkill("qianlong")
caomao:addSkill("fensi")
caomao:addSkill("juetao")
caomao:addSkill("zhushi")
Fk:loadTranslationTable{
  ["joy__caomao"] = "曹髦",
  ["#joy__caomao"] = "霸业的终耀",
}

local liuzan = General(extension, "joy__liuzan", "wu", 4)
liuzan:addSkill("ty__fenyin")
liuzan:addSkill("liji")
Fk:loadTranslationTable{
  ["joy__liuzan"] = "留赞",
  ["#joy__liuzan"] = "啸天亢声",
}

local puyuan = General(extension, "joy__puyuan", "shu", 4)
puyuan:addSkill("tianjiang")
puyuan:addSkill("zhuren")
Fk:loadTranslationTable{
  ["joy__puyuan"] = "蒲元",
  ["#joy__puyuan"] = "淬炼百兵",
}

local nanhualaoxian = General(extension, "joy__laoxian", "qun", 4)
nanhualaoxian:addSkill("gongxiu")
nanhualaoxian:addSkill("jinghe")
nanhualaoxian:addRelatedSkill("ex__leiji")
nanhualaoxian:addRelatedSkill("yinbingn")
nanhualaoxian:addRelatedSkill("huoqi")
nanhualaoxian:addRelatedSkill("guizhu")
nanhualaoxian:addRelatedSkill("xianshou")
nanhualaoxian:addRelatedSkill("lundao")
nanhualaoxian:addRelatedSkill("guanyue")
nanhualaoxian:addRelatedSkill("yanzhengn")
nanhualaoxian:addRelatedSkill("ex__biyue")
nanhualaoxian:addRelatedSkill("ex__tuxi")
nanhualaoxian:addRelatedSkill("mingce")
nanhualaoxian:addRelatedSkill("zhiyan")
Fk:loadTranslationTable{
  ["joy__laoxian"] = "南华老仙",
  ["#joy__laoxian"] = "仙人指路",
}



local xiahoujie = General(extension, "joy__xiahoujie", "wei", 5)
xiahoujie:addSkill("liedan")
xiahoujie:addSkill("zhuangdan")
Fk:loadTranslationTable{
  ["joy__xiahoujie"] = "夏侯杰",
  ["#joy__xiahoujie"] = "当阳虎胆",
}

local sunyi = General(extension, "joy__sunyi", "wu", 5)
local xiongyis = fk.CreateTriggerSkill{
  name = "joy__xiongyis",
  anim_type = "defensive",
  frequency = Skill.Limited,
  events = {fk.AskForPeaches},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.dying and player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  on_cost = function(self, event, target, player, data)
    local prompt = "#xiongyis1-invoke:::"..tostring(math.min(3, player.maxHp))
    if table.find(player.room.alive_players, function(p)
      return p.general == "joy__xushi" or p.deputyGeneral == "joy__xushi" end)
    then
      prompt = "#xiongyis2-invoke"
    end
    if player.room:askForSkillInvoke(player, self.name, nil, prompt) then
      self.cost_data = prompt
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = tonumber(string.sub(self.cost_data, 10, 10))
    if n == 1 then
      local maxHp = player.maxHp
      room:recover({
        who = player,
        num = math.min(3, maxHp) - player.hp,
        recoverBy = player,
        skillName = self.name
      })
      room:changeHero(player, "joy__xushi", false, false, true, false)
    else
      room:recover({
        who = player,
        num = 1 - player.hp,
        recoverBy = player,
        skillName = self.name
      })
      room:handleAddLoseSkills(player, "joy__hunzi", nil, true, false)
    end
  end,
}
local hunzi = fk.CreateTriggerSkill{
  name = "joy__hunzi",
  frequency = Skill.Wake,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      player:usedSkillTimes(self.name, Player.HistoryGame) == 0 and
      player.phase == Player.Start
  end,
  can_wake = function(self, event, target, player, data)
    return player.hp == 1
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:changeMaxHp(player, -1)
    room:handleAddLoseSkills(player, "ex__yingzi|joy__yinghun", nil, true, false)
  end,
}
sunyi:addSkill("jiqiaos")
sunyi:addSkill(xiongyis)
sunyi:addRelatedSkill(hunzi)
sunyi:addRelatedSkill("ex__yingzi")
sunyi:addRelatedSkill("joy__yinghun")
Fk:loadTranslationTable{
  ["joy__sunyi"] = "孙翊",
  ["#joy__sunyi"] = "虓风快意",

  ["joy__xiongyis"] = "凶疑",
  [":joy__xiongyis"] = "限定技，当你处于濒死状态时，若徐氏：不在场，你可以将体力值回复至3点并将武将牌替换为徐氏；"..
  "在场，你可以将体力值回复至1点并获得技能〖魂姿〗。",
  ["joy__hunzi"] = "魂姿",
  [":joy__hunzi"] = "觉醒技，准备阶段，若你的体力为1，你减一点体力上限，然后获得“英姿”和“英魂”",

  ["#xiongyis1-invoke"] = "凶疑：你可以将回复体力至%arg点并变身为徐氏！",
  ["#xiongyis2-invoke"] = "凶疑：你可以将回复体力至1点并获得〖魂姿〗！",

  ["$ex__yingzi_joy__sunyi"] = "骁悍果烈，威震江东！",
}

local xurong = General(extension, "joy__xurong", "qun", 4)
local xionghuo = fk.CreateActiveSkill{
  name = "joy__xionghuo",
  anim_type = "offensive",
  card_num = 0,
  target_num = 1,
  can_use = function(self, player)
    return player:getMark("@joy__baoli") > 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected)
    return #selected == 0 and to_select ~= Self.id and Fk:currentRoom():getPlayerById(to_select):getMark("@joy__baoli") == 0
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:removePlayerMark(player, "@joy__baoli", 1)
    room:addPlayerMark(target, "@joy__baoli", 1)
  end,
}
local xionghuo_record = fk.CreateTriggerSkill{
  name = "#joy__xionghuo_record",
  main_skill = xionghuo,
  anim_type = "offensive",
  events = {fk.GameStart, fk.DamageCaused, fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(xionghuo) then
      if event == fk.GameStart then
        return true
      elseif event == fk.DamageCaused then
        return target == player and data.to ~= player and data.to:getMark("@joy__baoli") > 0
      else
        return target ~= player and target:getMark("@joy__baoli") > 0 and target.phase == Player.Play
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke("joy__xionghuo")
    if event == fk.GameStart then
      room:addPlayerMark(player, "@joy__baoli", 3)
    elseif event == fk.DamageCaused then
      room:doIndicate(player.id, {data.to.id})
      data.damage = data.damage + 1
    else
      room:doIndicate(player.id, {target.id})
      room:removePlayerMark(target, "@joy__baoli", 1)
      local n = 3
      if target:isNude() then
        n = 2
      end
      local rand = math.random(1, n)
      if rand == 1 then
        room:damage {
          from = player,
          to = target,
          damage = 1,
          damageType = fk.FireDamage,
          skillName = "joy__xionghuo",
        }
        local mark = target:getTableMark( "joy__xionghuo_prohibit-turn")
        table.insert(mark, player.id)
        room:setPlayerMark(target, "joy__xionghuo_prohibit-turn", mark)

      elseif rand == 2 then
        room:loseHp(target, 1, "joy__xionghuo")
        room:addPlayerMark(target, "MinusMaxCards-turn", 1)
      else
        local dummy = Fk:cloneCard("dilu")
        if not target:isKongcheng() then
          dummy:addSubcard(table.random(target.player_cards[Player.Hand]))
        end
        if #target.player_cards[Player.Equip] > 0 then
          dummy:addSubcard(table.random(target.player_cards[Player.Equip]))
        end
        room:obtainCard(player.id, dummy, false, fk.ReasonPrey)
      end
    end
  end,
}
local xionghuo_prohibit = fk.CreateProhibitSkill{
  name = "#joy__xionghuo_prohibit",
  is_prohibited = function(self, from, to, card)
    return card.trueName == "slash" and table.contains(from:getTableMark( "joy__xionghuo_prohibit-turn") ,to.id)
  end,
}
local shajue = fk.CreateTriggerSkill{
  name = "joy__shajue",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = {fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    return target ~= player and player:hasSkill(self) and target.hp < 0
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:addPlayerMark(player, "@joy__baoli", 1)
    if data.damage and data.damage.card and U.hasFullRealCard(room, data.damage.card) then
      room:obtainCard(player, data.damage.card, true, fk.ReasonPrey)
    end
  end
}
xionghuo:addRelatedSkill(xionghuo_record)
xionghuo:addRelatedSkill(xionghuo_prohibit)
xurong:addSkill(xionghuo)
xurong:addSkill(shajue)
Fk:loadTranslationTable{
  ["joy__xurong"] = "徐荣",
  --其实就是老徐荣

  ["joy__xionghuo"] = "凶镬",
  [":joy__xionghuo"] = "游戏开始时，你获得3个“暴戾”标记。出牌阶段，你可以交给一名其他角色一个“暴戾”标记，你对有此标记的角色造成的伤害+1，"..
  "且其出牌阶段开始时，移去“暴戾”并随机执行一项："..
  "1.受到1点火焰伤害且本回合不能对你使用【杀】；"..
  "2.流失1点体力且本回合手牌上限-1；"..
  "3.你随机获得其一张手牌和一张装备区里的牌。",
  ["joy__shajue"] = "杀绝",
  [":joy__shajue"] = "锁定技，其他角色进入濒死状态时，若其需要超过一张【桃】或【酒】救回，则你获得一个“暴戾”标记，并获得使其进入濒死状态的牌。",
  ["#joy__xionghuo_record"] = "凶镬",
  ["@joy__baoli"] = "暴戾",

}



local chunyuqiong = General(extension, "joy__chunyuqiong", "qun", 4)
chunyuqiong:addSkill("cangchu")
chunyuqiong:addSkill("liangying")
local shishou = fk.CreateTriggerSkill{
  name = "joy__shishou",
  events = { fk.CardUseFinished, fk.Damaged},
  anim_type = "negative",
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and target == player then
      if event == fk.CardUseFinished then
        return player:getMark("@cangchu") > 0 and data.card.name == "analeptic"
      else
        return player:getMark("@cangchu") > 0 and data.damageType == fk.FireDamage
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
      room:removePlayerMark(player, "@cangchu")
      room:broadcastProperty(player, "MaxCards")
  end,
}
chunyuqiong:addSkill(shishou)
Fk:loadTranslationTable{
  ["joy__chunyuqiong"] = "淳于琼",
  ["#joy__chunyuqiong"] = "西原右校尉",
  ["joy__shishou"] = "失守",
  [":joy__shishou"] = "锁定技，当你使用【酒】或受到火焰伤害后，你失去1枚“粮”。",
}


local joy__simahui = General(extension, "joy__simahui", "qun", 3)
local doJianjieMarkChange = function (room, player, mark, acquired, proposer)
  local skill = (mark == "@@joy__dragon_mark") and "jjj__huoji&" or "jjj__lianhuan&"
  room:setPlayerMark(player, mark, acquired and 1 or 0)
  if not acquired then skill = "-"..skill end
  room:handleAddLoseSkills(player, skill, nil, false)
  local double_mark = (player:getMark("@@joy__dragon_mark") > 0 and player:getMark("@@joy__phoenix_mark") > 0)
  local yy_skill = double_mark and "jjj__yeyan&" or "-jjj__yeyan&"
  room:handleAddLoseSkills(player, yy_skill, nil, false)
  if acquired then
    proposer:broadcastSkillInvoke("joy__jianjie", double_mark and 3 or math.random(2))
  end
end
local joy__jianjie = fk.CreateActiveSkill{
  name = "joy__jianjie",
  anim_type = "control",
  mute = true,
  can_use = function(self, player)
    return player:getMark("joy__jianjie-turn") == 0 and player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  interaction = function()
    return UI.ComboBox {choices = {"joy__dragon_mark_move", "joy__phoenix_mark_move"}}
  end,
  card_num = 0,
  card_filter = Util.FalseFunc,
  target_num = 2,
  target_filter = function(self, to_select, selected)
    if #selected == 2 or not self.interaction.data then return false end
    local to = Fk:currentRoom():getPlayerById(to_select)
    local mark = (self.interaction.data == "joy__dragon_mark_move") and "@@joy__dragon_mark" or "@@joy__phoenix_mark"
    if #selected == 0 then
      return to:getMark(mark) > 0
    else
      return to:getMark(mark) == 0
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:notifySkillInvoked(player, self.name)
    local from = room:getPlayerById(effect.tos[1])
    local to = room:getPlayerById(effect.tos[2])
    local mark = (self.interaction.data == "joy__dragon_mark_move") and "@@joy__dragon_mark" or "@@joy__phoenix_mark"
    doJianjieMarkChange (room, from, mark, false, player)
    doJianjieMarkChange (room, to, mark, true, player)
  end,
}
local jianjie_trigger = fk.CreateTriggerSkill{
  name = "#joy__jianjie_trigger",
  events = {fk.TurnStart, fk.Death},
  main_skill = joy__jianjie,
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if event == fk.TurnStart then
      return player:hasSkill(self) and player:getMark("joy__jianjie-turn") > 0
    else
      return player:hasSkill(self) and (target:getMark("@@joy__dragon_mark") > 0 or target:getMark("@@joy__phoenix_mark") > 0)
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.TurnStart then return true end
    local room = player.room
    local gives = {}
    if target:getMark("@@joy__dragon_mark") > 0 then
      local dra_tars = table.filter(room.alive_players, function(p) return p:getMark("@@joy__dragon_mark") == 0 end)
      if #dra_tars > 0 then
        local tos = room:askForChoosePlayers(player, table.map(dra_tars, Util.IdMapper), 1, 1, "#joy__dragon_mark-move::"..target.id, self.name, true)
        if #tos > 0 then
          table.insert(gives, {"@@joy__dragon_mark", tos[1]})
        end
      end
    end
    if target:getMark("@@joy__phoenix_mark") > 0 then
      local dra_tars = table.filter(room.alive_players, function(p) return p:getMark("@@joy__phoenix_mark") == 0 end)
      if #dra_tars > 0 then
        local tos = room:askForChoosePlayers(player, table.map(dra_tars, Util.IdMapper), 1, 1, "#joy__phoenix_mark-move::"..target.id, self.name, true)
        if #tos > 0 then
          table.insert(gives, {"@@joy__phoenix_mark", tos[1]})
        end
      end
    end
    if #gives > 0 then
      self.cost_data = gives
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:notifySkillInvoked(player, "joy__jianjie")
    if event == fk.TurnStart then
      local dra_tars = table.filter(room.alive_players, function(p) return p:getMark("@@joy__dragon_mark") == 0 end)
      local dra
      if #dra_tars > 0 then
        local tos = room:askForChoosePlayers(player, table.map(dra_tars, Util.IdMapper), 1, 1, "#joy__dragon_mark-give", self.name, false)
        if #tos > 0 then
          dra = room:getPlayerById(tos[1])
          doJianjieMarkChange (room, dra, "@@joy__dragon_mark", true, player)
        end
      end
      local pho_tars = table.filter(room.alive_players, function(p) return p:getMark("@@joy__phoenix_mark") == 0 end)
      table.removeOne(pho_tars, dra)
      if #pho_tars > 0 then
        local tos = room:askForChoosePlayers(player, table.map(pho_tars, Util.IdMapper), 1, 1, "#joy__phoenix_mark-give", self.name, false)
        if #tos > 0 then
          local pho = room:getPlayerById(tos[1])
          doJianjieMarkChange (room, pho, "@@joy__phoenix_mark", true, player)
        end
      end
    else
      for _, dat in ipairs(self.cost_data) do
        local mark = dat[1]
        local p = room:getPlayerById(dat[2])
        doJianjieMarkChange (room, p, mark, true, player)
      end
    end
  end,

  refresh_events = {fk.TurnStart, fk.EventAcquireSkill},
  can_refresh = function (self, event, target, player, data)
    if event == fk.TurnStart then
      return player:hasSkill(self,true) and target == player
    else
      return target == player and data == self and player.room:getTag("RoundCount")
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    local current_event = room.logic:getCurrentEvent()
    if not current_event then return end
    local turn_event = current_event:findParent(GameEvent.Turn, true)
    if not turn_event then return end
    local events = room.logic.event_recorder[GameEvent.Turn] or Util.DummyTable
    for _, e in ipairs(events) do
      local current_player = e.data[1]
      if current_player == player then
        if turn_event.id == e.id then
          room:setPlayerMark(player, "joy__jianjie-turn", 1)
        end
        break
      end
    end
  end,
}
joy__jianjie:addRelatedSkill(jianjie_trigger)
joy__simahui:addSkill(joy__jianjie)

joy__simahui:addSkill("chenghao")
local joy__yinshi = fk.CreateTriggerSkill{
  name = "joy__yinshi",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target == player and (data.damageType ~= fk.NormalDamage or (data.card and data.card.type == Card.TypeTrick)) and (player:getMark("@@joy__dragon_mark") == 0 or player:getMark("@@joy__phoenix_mark") == 0) and #player:getEquipments(Card.SubtypeArmor) == 0
  end,
  on_use = Util.TrueFunc,
}
joy__simahui:addSkill(joy__yinshi)
local jjj__lianhuan = fk.CreateActiveSkill{
  name = "jjj__lianhuan&",
  card_num = 1,
  min_target_num = 0,
  can_use = function(self, player)
    return not player:isKongcheng() and player:usedSkillTimes(self.name, Player.HistoryTurn) < 3
  end,
  card_filter = function(self, to_select, selected, selected_targets)
    return #selected == 0 and Fk:getCardById(to_select).suit == Card.Club and Fk:currentRoom():getCardArea(to_select) ~= Player.Equip
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    if #selected_cards == 1 then
      local card = Fk:cloneCard("iron_chain")
      card:addSubcard(selected_cards[1])
      return card.skill:canUse(Self, card) and card.skill:targetFilter(to_select, selected, selected_cards, card) and
      not Self:prohibitUse(card) and not Self:isProhibited(Fk:currentRoom():getPlayerById(to_select), card)
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    if #effect.tos == 0 then
      room:recastCard(effect.cards, player, self.name)
    else
      room:sortPlayersByAction(effect.tos)
      room:useVirtualCard("iron_chain", effect.cards, player, table.map(effect.tos, Util.Id2PlayerMapper), self.name)
    end
  end,
}
Fk:addSkill(jjj__lianhuan)
local jjj__huoji__fireAttackSkill = fk.CreateActiveSkill{
  name = "jjj__huoji__fire_attack_skill",
  prompt = "#fire_attack_skill",
  target_num = 1,
  mod_target_filter = function(_, to_select, _, _, _, _)
    return not Fk:currentRoom():getPlayerById(to_select):isKongcheng()
  end,
  target_filter = function(self, to_select, selected, _, card)
    if #selected < self:getMaxTargetNum(Self, card) then
      return self:modTargetFilter(to_select, selected, Self.id, card)
    end
  end,
  on_effect = function(self, room, cardEffectEvent)
    local from = room:getPlayerById(cardEffectEvent.from)
    local to = room:getPlayerById(cardEffectEvent.to)
    if to:isKongcheng() then return end
    local showCard = room:askForCard(to, 1, 1, false, self.name, false, ".|.|.|hand", "#fire_attack-show:" .. from.id)[1]
    to:showCards(showCard)
    local suit = Fk:getCardById(showCard):getSuitString()
    local top = room:getNCards(4)
    for i = 4, 1, -1 do
      table.insert(room.draw_pile, 1, top[i])
    end
    local can_throw = table.filter(top, function(id) return Fk:getCardById(id):getSuitString() == suit end)
    local ids , _ = U.askforChooseCardsAndChoice(from, can_throw, {"OK"}, self.name, "#joy__huoji-card", {"Cancel"}, 1, 1, top)
    if #ids == 0 and not from:isKongcheng() then
      ids = room:askForDiscard(from, 1, 1, false, self.name, true,
      ".|.|" .. suit, "#fire_attack-discard:" .. to.id .. "::" .. suit, true)
    end
    if #ids > 0 then
      room:throwCard(ids, self.name, from, from)
      room:damage({
        from = from,
        to = to,
        card = cardEffectEvent.card,
        damage = 1,
        damageType = fk.FireDamage,
        skillName = self.name
      })
    end
  end,
}
jjj__huoji__fireAttackSkill.cardSkill = true
Fk:addSkill(jjj__huoji__fireAttackSkill)
local jjj__huoji = fk.CreateViewAsSkill{
  name = "jjj__huoji&",
  anim_type = "offensive",
  pattern = "fire_attack",
  prompt = "#huoji",
  card_filter = function(self, to_select, selected)
    return #selected == 0 and Fk:getCardById(to_select).color == Card.Red and Fk:currentRoom():getCardArea(to_select) ~= Player.Equip 
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then return end
    local card = Fk:cloneCard("fire_attack")
    card.skillName = self.name
    card:addSubcard(cards[1])
    return card
  end,
  enabled_at_play = function(self, player)
    return not player:isKongcheng() and player:usedSkillTimes(self.name, Player.HistoryTurn) < 3
  end,
}
local huoji_trigger = fk.CreateTriggerSkill{
  name = "#jjj__huoji_trigger",
  events = {fk.PreCardEffect},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill("jjj__huoji&") and data.from == player.id and data.card.trueName == "fire_attack"
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local card = data.card:clone()
    local c = table.simpleClone(data.card)
    for k, v in pairs(c) do
      card[k] = v
    end
    card.skill = jjj__huoji__fireAttackSkill
    data.card = card
  end,
}
jjj__huoji:addRelatedSkill(huoji_trigger)
Fk:addSkill(jjj__huoji)
local jjj__yeyan = fk.CreateActiveSkill{
  name = "jjj__yeyan&",
  anim_type = "offensive",
  min_target_num = 1,
  max_target_num = 3,
  min_card_num = 0,
  max_card_num = 4,
  frequency = Skill.Limited,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  card_filter = function(self, to_select, selected)
    return table.contains(Self.player_cards[Player.Hand], to_select) and not Self:prohibitDiscard(Fk:getCardById(to_select))
    and table.every(selected, function (id) return Fk:getCardById(to_select).suit ~= Fk:getCardById(id).suit end)
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    if #selected_cards == 4 then
      return #selected < 2
    elseif #selected_cards == 0 then
      return #selected < 3
    else
      return false
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    
    local damageMap = {}
    if #effect.cards == 0 then
      for _, pid in ipairs(effect.tos) do
        damageMap[pid] = 1
      end
    else
      if #effect.tos == 1 then
        local choice = room:askForChoice(player, {"3", "2"}, self.name)
        damageMap[effect.tos[1]] = tonumber(choice)
      else
        local tos = room:askForChoosePlayers(player, effect.tos, 1, 1, "#yeyan-choose", self.name, false)
        damageMap[tos[1]] = 2
        damageMap[tos[1] == effect.tos[1] and effect.tos[2] or effect.tos[1]] = 1
      end
      room:throwCard(effect.cards, self.name, player, player)
      doJianjieMarkChange (room, player, "@@joy__dragon_mark", false, player)
      doJianjieMarkChange (room, player, "@@joy__phoenix_mark", false, player)
    end
    room:sortPlayersByAction(effect.tos)
    for _, pid in ipairs(effect.tos) do
      local to = room:getPlayerById(pid)
      if not to.dead then
        room:damage{
          from = player,
          to = to,
          damage = damageMap[pid],
          damageType = fk.FireDamage,
          skillName = self.name,
        }
      end
    end
  end,
}
Fk:addSkill(jjj__yeyan)
Fk:loadTranslationTable{
  ["joy__simahui"] = "司马徽",
  ["#joy__simahui"] = "水镜先生",

  ["joy__jianjie"] = "荐杰",
  [":joy__jianjie"] = "①你的第一个回合开始时，你令一名两名角色分别获得“龙印”与“凤印”；②出牌阶段限一次（你的第一个回合除外），或当拥有“龙印”/“凤印”的角色死亡时，你可以转移“龙印”/“凤印”。"..
  "<br><font color='grey'>•拥有 “龙印”/“凤印” 的角色视为拥有技能“火计”/“连环”（均一回合限三次）；"..
  "<br>•同时拥有“龙印”和“凤印”的角色视为拥有技能“业炎”。",
  ["#joy__jianjie_trigger"] = "荐杰",
  ["@@joy__dragon_mark"] = "龙印",
  ["@@joy__phoenix_mark"] = "凤印",
  ["#joy__dragon_mark-give"] = "荐杰：令一名角色获得“龙印”",
  ["#joy__phoenix_mark-give"] = "荐杰：令一名角色获得“凤印”",
  ["#joy__dragon_mark-move"] = "荐杰：令一名角色获得 %dest 的“龙印”",
  ["#joy__phoenix_mark-move"] = "荐杰：令一名角色获得 %dest 的“凤印”",
  ["joy__dragon_mark_move"] = "转移“龙印”",
  ["joy__phoenix_mark_move"] = "转移“凤印”",

  ["joy__yinshi"] = "隐士",
  [":joy__yinshi"] = "锁定技，若你没同时拥有“龙印”和“凤印”且装备区内没有防具牌，防止受到的属性伤害与锦囊牌造成的伤害。",

  ["jjj__lianhuan&"] = "连环",
  [":jjj__lianhuan&"] = "你可以将一张梅花手牌当【铁索连环】使用或重铸（每回合限三次）。",
  ["jjj__huoji&"] = "火计",
  [":jjj__huoji&"] = "每回合限三次，你可以将一张红色手牌当【火攻】使用，你可以观看牌堆顶的4张牌，选择其中一张代替火攻需弃置的牌，其余的牌放回牌堆顶。",
  ["jjj__huoji__fire_attack_skill"] = "火攻",
  ["#jjj__huoji_trigger"] = "火计",
  
  ["jjj__yeyan&"] = "业炎",
  [":jjj__yeyan&"] = "限定技，出牌阶段，你可以选择至多三名角色，你分别对这些角色造成至多共计3点火焰伤害；若你对一名角色分配2点或更多的火焰伤害，你须先弃置四张不同花色的手牌和龙凤印。",
  ["#jjj__yeyan-choose"] = "业炎：选择第%arg点伤害的目标",

}


local zhangfen = General(extension, "joy__zhangfen", "wu", 4)
local wanglu_engine = {{"joy__siege_engine", Card.Spade, 9}}
local wanglu = fk.CreateTriggerSkill{
  name = "joy__wanglu",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Start
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if table.find(player:getEquipments(Card.SubtypeWeapon), function(id) return Fk:getCardById(id).name == "joy__siege_engine" end) then
      player:gainAnExtraPhase(Player.Play)
    else
      local engine = table.find(U.prepareDeriveCards(room, wanglu_engine, "joy__wanglu_engine"), function (id)
        return room:getCardArea(id) == Card.Void
      end)
      if engine and U.canMoveCardIntoEquip(player, engine) then
        for i = 1, 3, 1 do
          room:setPlayerMark(player, "joy__xianzhu"..tostring(i), 0)
        end
        U.moveCardIntoEquip (room, player, engine, self.name, true, player)
      end
    end
  end,
}
local xianzhu_trigger = fk.CreateTriggerSkill{
  name = "#joy__xianzhu_trigger",
  anim_type = "offensive",
  events = {fk.Damage},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card and data.card.trueName == "slash" and
    table.find(player:getEquipments(Card.SubtypeWeapon), function(id) return Fk:getCardById(id).name == "joy__siege_engine" end)
    and (player:getMark("joy__xianzhu1") + player:getMark("joy__xianzhu2") + player:getMark("joy__xianzhu3")) < 5
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local choices = {"joy__xianzhu2", "joy__xianzhu3"}
    if player:getMark("joy__xianzhu1") == 0 then
      table.insert(choices, 1, "joy__xianzhu1")
    end
    local choice = room:askForChoice(player, choices, self.name, "#xianzhu-choice")
    room:addPlayerMark(player, choice, 1)
  end,
}
local xianzhu = fk.CreateActiveSkill{
  name = "joy__xianzhu",
  anim_type = "offensive",
  card_num = 1,
  target_num = 1,
  can_use = function(self, player)
    return not player:isNude() and player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = function(self, to_select, selected, targets)
    return #selected == 0 and Fk:getCardById(to_select).sub_type == Card.SubtypeWeapon and Fk:currentRoom():getCardArea(to_select) ~= Card.PlayerEquip
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    return #selected == 0 and to_select ~= Self.id and not Self:isProhibited(Fk:currentRoom():getPlayerById(to_select), Fk:cloneCard("slash"))
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:throwCard(effect.cards,self.name,player)
    local use = {
      from = player.id,
      tos = {{target.id}},
      card = Fk:cloneCard("slash"),
      skillName = self.name,
      extraUse = true,
    }
    room:useCard(use)
  end,
}
local chaixie = fk.CreateTriggerSkill{
  name = "joy__chaixie",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      for _, move in ipairs(data) do
        if move.toArea == Card.Void then
          for _, info in ipairs(move.moveInfo) do
            if Fk:getCardById(info.cardId, true).name == "joy__siege_engine" then
              return true
            end
          end
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = 0
    for i = 1, 3, 1 do
      n = n + player:getMark("joy__xianzhu"..tostring(i))
      room:setPlayerMark(player, "joy__xianzhu"..tostring(i), 0)
    end
    player:drawCards(n, self.name)
  end,

  refresh_events = {fk.BeforeCardsMove},
  can_refresh = Util.TrueFunc,
  on_refresh = function(self, event, target, player, data)
    local mirror_moves = {}
    local to_void, cancel_move = {},{}
    local no_updata = (player:getMark("joy__xianzhu1") + player:getMark("joy__xianzhu2") + player:getMark("joy__xianzhu3")) == 0
    for _, move in ipairs(data) do
      if move.from == player.id and move.toArea ~= Card.Void then
        local move_info = {}
        local mirror_info = {}
        for _, info in ipairs(move.moveInfo) do
          local id = info.cardId
          if Fk:getCardById(id, true).name == "joy__siege_engine" and info.fromArea == Card.PlayerEquip then
            if no_updata and move.moveReason == fk.ReasonDiscard then
              table.insert(cancel_move, id)
            else
              table.insert(mirror_info, info)
              table.insert(to_void, id)
            end
          else
            table.insert(move_info, info)
          end
        end
        move.moveInfo = move_info
        if #mirror_info > 0 then
          local mirror_move = table.clone(move)
          mirror_move.to = nil
          mirror_move.toArea = Card.Void
          mirror_move.moveInfo = mirror_info
          table.insert(mirror_moves, mirror_move)
        end
      end
    end
    if #cancel_move > 0 then
      player.room:sendLog{ type = "#cancelDismantle", card = cancel_move, arg = "#siege_engine_skill"  }
    end
    if #to_void > 0 then
      table.insertTable(data, mirror_moves)
      player.room:sendLog{ type = "#destructDerivedCards", card = to_void, }
    end
  end,
}
xianzhu:addRelatedSkill(xianzhu_trigger)
zhangfen:addSkill(wanglu)
zhangfen:addSkill(xianzhu)
zhangfen:addSkill(chaixie)
Fk:loadTranslationTable{
  ["joy__zhangfen"] = "张奋",
  ["#joy__zhangfen"] = "御驰大攻",

  ["joy__wanglu"] = "望橹",
  [":joy__wanglu"] = "锁定技，准备阶段，你将【大攻车】置入你的装备区，若你的装备区内已有【大攻车】，则你执行一个额外的出牌阶段。<br>"..
  "<font color='grey'>【大攻车】<br>♠9 装备牌·武器<br /><b>攻击范围</b>：2<br /><b>武器技能</b>：出牌阶段开始时，你可以视为使用一张【杀】(不计次数），"..
  "当此【杀】对目标角色造成伤害后，你弃置其一张牌。若此牌未升级，则防止此牌被弃置。此牌离开装备区时销毁。",
  ["joy__xianzhu"] = "陷筑",
  [":joy__xianzhu"] = "出牌阶段限一次，你可以弃置手中的一张武器牌，然后视为对场上的一名角色使用了一张【杀】（无视距离且不计入次数）。<br>"..
  "当你使用【杀】造成伤害后，你可以升级【大攻车】（每个【大攻车】最多升级5次）。升级选项：<br>"..
  "【大攻车】的【杀】无视距离和防具（装备【大攻车】以后的所有杀）；<br>【大攻车】的【杀】可指定目标+1；<br>【大攻车】的【杀】造成伤害后弃牌数+1。",
  ["joy__chaixie"] = "拆械",
  [":joy__chaixie"] = "锁定技，当【大攻车】销毁后，你摸X张牌（X为该【大攻车】的升级次数）。",
  ["#joy__xianzhu-choice"] = "陷筑：选择【大攻车】使用【杀】的增益效果",
  ["joy__xianzhu1"] = "无视距离和防具",
  ["joy__xianzhu2"] = "可指定目标+1",
  ["joy__xianzhu3"] = "造成伤害后弃牌数+1",
  ["#joy__xianzhu_trigger"] = "陷筑",

  ["$joy__wanglu1"] = " ",
  ["$joy__wanglu2"] = " ",
  ["$joy__xianzhu1"] = " ",
  ["$joy__xianzhu2"] = " ",
  ["$joy__chaixie1"] = " ",
  ["$joy__chaixie2"] = " ",
  ["~joy__zhangfen"] = " ",
}

local chengyu = General(extension, "joy__chengyu", "wei", 3)
local shefu = fk.CreateTriggerSkill{
  name = "joy__shefu",
  anim_type = "control",
  derived_piles = "joy__shefu",
  events ={fk.EventPhaseStart, fk.Damaged,fk.CardUsing},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.EventPhaseStart then
        return target == player and player.phase == Player.Finish and not player:isNude()
      elseif event == fk.Damaged then
        return target == player and not player:isNude()
      else
        return target ~= player and player.phase == Player.NotActive and data.card.type ~= Card.TypeEquip and U.IsUsingHandcard(target, data)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart or event == fk.Damaged then
      local cards = room:askForCard(player, 1, 1, true, self.name, true, ".", "#joy__shefu-cost")
      if #cards > 0 then
        self.cost_data = cards[1]
        return true
      end
    else
      local index
      local mark = player:getTableMark( self.name)
      for i = 1, #mark, 1 do
        if data.card.trueName == mark[i][2] then
          index = i
          break
        end
      end
      if index and room:askForSkillInvoke(player, self.name, nil, "#joy__shefu-invoke::"..target.id..":"..data.card.name) then
        self.cost_data = index
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart or event == fk.Damaged then
      player:addToPile(self.name, self.cost_data, false, self.name)
      local names = {}
      local mark = player:getTableMark( self.name)
      for _, id in ipairs(Fk:getAllCardIds()) do
        local card = Fk:getCardById(id)
        if card.type ~= Card.TypeEquip then
          table.insertIfNeed(names, card.trueName)
        end
      end
      if #names > 0 then
        local name = room:askForChoice(player, names, self.name)
        table.insert(mark, {self.cost_data, name})
        room:setPlayerMark(player, self.name, mark)
      end
    else
      local index = self.cost_data
      local mark = player:getTableMark( self.name)
      local throw = mark[index][1]
      table.remove(mark, index)
      room:setPlayerMark(player, self.name, mark)
      if target.phase ~= Player.NotActive then
        room:setPlayerMark(target, "@@joy__shefu-turn", 1)
      end
      room:moveCards({
        from = player.id,
        ids = {throw},
        toArea = Card.DiscardPile,
        moveReason = fk.ReasonPutIntoDiscardPile,
        skillName = self.name,
        specialName = self.name,
      })
      data.tos = {}
      room:sendLog{ type = "#CardNullifiedBySkill", from = target.id, arg = self.name, arg2 = data.card:toLogString() }
    end
  end,
}
local shefu_invalidity = fk.CreateInvaliditySkill {
  name = "#joy__shefu_invalidity",
  invalidity_func = function(self, from, skill)
    return from:getMark("@@joy__shefu-turn") > 0 and not skill.attached_equip and not skill.name:endsWith("&")
  end
}
shefu:addRelatedSkill(shefu_invalidity)
chengyu:addSkill(shefu)
local benyu = fk.CreateTriggerSkill{
  name = "joy__benyu",
  anim_type = "masochism",
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.from and not data.from.dead
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if room:askForSkillInvoke(player,self.name) then
      local choices = {}
      if not player:isKongcheng() then
        table.insert(choices,"joy__benyu-damage::"..data.from.id)
      end
      local x = math.min(data.from:getHandcardNum(), 5)
      if player:getHandcardNum() < x  then
        table.insert(choices,"joy__benyu-drawcards:::"..x)
      end
      if #choices > 0 then
        local choice = room:askForChoice(player,choices,self.name,"#joy__benyu-ask")
        if choice == "joy__benyu-damage::"..data.from.id then
          local card = room:askForCard(player,1,1,false,self.name,true,".","#joy__benyu-damage::"..data.from.id)
          if #card > 0 then
            self.cost_data = {choice,card}
            return true
          end
        elseif choice == "joy__benyu-drawcards:::"..x then
            self.cost_data = {choice}
            return true
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if self.cost_data[1] == "joy__benyu-damage::"..data.from.id then
      player.room:throwCard(self.cost_data[2], self.name, player, player)
      player.room:damage{
        from = player,
        to = data.from,
        damage = 1,
        skillName = self.name,
      }
    else
      player:drawCards(math.min(5, data.from:getHandcardNum()) - player:getHandcardNum())
    end
  end,
}
chengyu:addSkill(benyu)
Fk:loadTranslationTable{
  ["joy__chengyu"] = "程昱",
  ["#joy__chengyu"] = "泰山捧日",

  ["joy__shefu"] = "设伏",
  [":joy__shefu"] = "①结束阶段和受到伤害后，你可以记录一个基本牌或锦囊牌的牌名并扣置一张牌，称为“伏兵”；<br>"..
  "②当其他角色于你回合外使用手牌时，你可以移去一张记录牌名相同的“伏兵”，令此牌无效（若此牌有目标角色则改为取消所有目标），然后若此时是该角色的回合内，其本回合所有技能失效。",
  ["joy__benyu"] = "贲育",
  [":joy__benyu"] = "当你受到伤害后，你可以选择一项：1.将手牌摸至与伤害来源相同（最多摸至5张）；2.弃置1张牌，然后对伤害来源造成1点伤害。",
  ["#joy__shefu-cost"] = "设伏：你可以将一张牌扣置为“伏兵”",
  ["#joy__benyu-damage"] = "贲育：选择弃置一张手牌，对 %dest 造成1点伤害",
  ["joy__benyu-drawcards"] = "摸至 %arg 张牌",
  ["joy__benyu-damage"] = "弃一张牌对 %dest 造成1点伤害",
  ["@@joy__shefu-turn"] = "设伏封技",
  ["#joy__shefu-invoke"] = "设伏：可以令 %dest 使用的 %arg 无效",
  ["#CardNullifiedBySkill"] = "由于 %arg 的效果，%from 使用的 %arg2 无效",
  ["#joy__benyu-ask"] = "贲育",

  ["$joy__shefu1"] = " ",
  ["$joy__shefu2"] = " ",
  ["$joy__benyu1"] = " ",
  ["$joy__benyu2"] = " ",
  ["~joy__chengyu"] = " ",
}

local longfeng = General(extension, "joy__wolongfengchu", "shu", 4)
local joy__youlong = fk.CreateViewAsSkill{
  name = "joy__youlong",
  switch_skill_name = "joy__youlong",
  anim_type = "switch",
  pattern = ".",
  prompt = function ()
    return "#joy__youlong-prompt"..Self:getSwitchSkillState("joy__youlong")
  end,
  interaction = function()
    local names = {}
    local mark = Self:getTableMark( "@$joy__youlong")
    local isYang = Self:getSwitchSkillState("joy__youlong") == fk.SwitchYang
    for _, id in ipairs(Fk:getAllCardIds()) do
      local card = Fk:getCardById(id)
      if ((card.type == Card.TypeBasic and not isYang) or
        (card:isCommonTrick() and isYang)) and
        not card.is_derived and
        ((Fk.currentResponsePattern == nil and Self:canUse(card)) or
        (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(card))) then
        if not table.contains(mark, card.trueName) then
          table.insertIfNeed(names, card.name)
        end
      end
    end
    if #names == 0 then return end
    return UI.ComboBox {choices = names}
  end,
  card_filter = function (self, to_select, selected)
    return Self:getSwitchSkillState("joy__youlong") == fk.SwitchYin and #selected == 0
    and Fk:getCardById(to_select).type ~= Card.TypeBasic and not Self:prohibitDiscard(Fk:getCardById(to_select))
  end,
  view_as = function(self, cards)
    if not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    if Self:getSwitchSkillState("joy__youlong") == fk.SwitchYin then
      if #cards ~= 1 then return end
      card:setMark("joy__youlong_card", cards[1])
    end
    card.skillName = self.name
    return card
  end,
  before_use = function(self, player, use)
    local room = player.room
    local mark = player:getTableMark( "@$joy__youlong")
    table.insert(mark, use.card.trueName)
    room:setPlayerMark(player, "@$joy__youlong", mark)
    local state = player:getSwitchSkillState(self.name, true, true)
    room:setPlayerMark(player, "joy__youlong_" .. state .. "-turn", 1)
    if state == "yin" then
      local id = use.card:getMark("joy__youlong_card")
      if id ~= 0 then
        room:throwCard(id, self.name, player, player)
      end
    else
      local choices = player:getAvailableEquipSlots()
      if #choices == 0 then return end
      local choice = room:askForChoice(player, choices, self.name, "#joy__youlong-choice", false, player.equipSlots)
      room:abortPlayerArea(player, choice)
    end
  end,
  enabled_at_play = function(self, player)
    local state = player:getSwitchSkillState(self.name, false, true)
    if player:getMark("joy__youlong_" .. state .. "-turn") == 0 or player:getMark("joy__youlong_levelup") > 0 then
      return state == "yin" or#player:getAvailableEquipSlots() > 0
    end
  end,
  enabled_at_response = function(self, player, response)
    if response then return end
    local state = player:getSwitchSkillState(self.name, false, true)
    local pat = state == "yin" and "basic" or "trick"
    if Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):matchExp(".|0|nosuit|none|.|"..pat) then
      if player:getMark("joy__youlong_" .. state .. "-turn") == 0 or player:getMark("joy__youlong_levelup") > 0 then
        return state == "yin" or#player:getAvailableEquipSlots() > 0
      end
    end
  end,
}
local joy__luanfeng = fk.CreateTriggerSkill{
  name = "joy__luanfeng",
  frequency = Skill.Limited,
  events = {fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target.maxHp >= player.maxHp and target.dying
    and player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  on_cost = function (self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#joy__luanfeng-invoke:"..target.id)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:recover {
      who = target,
      num = 3 - target.hp,
      recoverBy = player,
      skillName = self.name,
    }
    local targets = {player}
    table.insertIfNeed(targets, target)
    for _, p in ipairs(targets) do
      if not p.dead then
        local slots = table.simpleClone(p.sealedSlots)
        table.removeOne(slots, Player.JudgeSlot)
        if #slots > 0 then
          room:resumePlayerArea(p, slots)
        end
      end
    end
    if not target.dead then
      local n = 6 - target:getHandcardNum()
      if n > 0 then
        target:drawCards(n, self.name)
      end
    end
    if player.dead then return end
    room:setPlayerMark(player, "joy__youlong_levelup", 1)
    room:setPlayerMark(player, "@$joy__youlong", 0)
  end,
}
longfeng:addSkill(joy__youlong)
longfeng:addSkill(joy__luanfeng)
Fk:loadTranslationTable{
  ["joy__wolongfengchu"] = "卧龙凤雏",
  ["#joy__wolongfengchu"] = "一匡天下",

  ["joy__youlong"] = "游龙",
  [":joy__youlong"] = "转换技，每回合各限一次，阳：你可以废除一个装备栏，视为使用一张未以此法使用过的普通锦囊牌；阴：你可以弃置一张非基本牌，视为使用一张未以此法使用过的基本牌。",
  ["joy__luanfeng" ] = "鸾凤",
  [":joy__luanfeng"] = "限定技，当一名角色进入濒死状态时，若其体力上限不小于你，" ..
  "你可令其将体力回复至3点，恢复你与其被废除的装备栏，令其手牌补至六张，" ..
  "然后去除〖游龙〗的回合次数限制，重置〖游龙〗使用过的牌名。",

  ["#joy__youlong-prompt0"] = "游龙：废除一个装备栏，视为使用一张未以此法使用过的普通锦囊牌",
  ["#joy__youlong-prompt1"] = "游龙：弃置一张非基本牌，视为使用一张未以此法使用过的基本牌",
  ["#joy__youlong-choice"] = "游龙: 请选择废除一个装备栏",
  ["@$joy__youlong"] = "游龙",
  ["#joy__luanfeng-invoke"] = "鸾凤：你可令 %src 将体力回复至3点，手牌补至六张",

  ['@$joy__youlong'] = '游龙',
  ['$joy__youlong1'] = '',
  ['$joy__youlong2'] = '',
  ['$joy__luanfeng1'] = '',
  ['$joy__luanfeng2'] = '',
  ['~joy__wolongfengchu'] = '',
}

local zhanglu = General(extension, "joy__zhanglu", "qun", 3)
local yishe = fk.CreateTriggerSkill{
  name = "joy__yishe",
  anim_type = "support",
  derived_piles = "joy__zhanglu_mi",
  events = {fk.EventPhaseStart, fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.EventPhaseStart then
        return target == player and player.phase == Player.Finish 
      else
        if #player:getPile("joy__zhanglu_mi") == 0 and player:isWounded() then
          for _, move in ipairs(data) do
            if move.from == player.id then
              for _, info in ipairs(move.moveInfo) do
                if info.fromSpecialName == "joy__zhanglu_mi" then
                  return true
                end
              end
            end
          end
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      return player.room:askForSkillInvoke(player, self.name, nil, "#joy__yishe-invoke")
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      player:drawCards(2, self.name)
      if player:isNude() then return end
      local dummy = Fk:cloneCard("dilu")
      local cards
      if #player:getCardIds("he") < 3 then
        cards = player:getCardIds("he")
      else
        cards = room:askForCard(player, 2, 2, true, self.name, false, ".", "#joy__yishe-cost")
      end
      dummy:addSubcards(cards)
      player:addToPile("joy__zhanglu_mi", dummy, true, self.name)
    else
      room:recover({
        who = player,
        num = 1,
        recoverBy = player,
        skillName = self.name
      })
    end
  end,
}
local bushi = fk.CreateTriggerSkill{
  name = "joy__bushi",
  anim_type = "masochism",
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player:hasSkill("joy__yishe") and (target == player or data.from == player) and #player:getPile("joy__zhanglu_mi") > 0 and not (data.from.dead or data.to.dead)
  end,
  on_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      self.cancel_cost = false
      for i = 1, data.damage do
        if #player:getPile("joy__zhanglu_mi") == 0 or self.cancel_cost then return end
        self:doCost(event, target, player, data)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local x
    if target == player then
      x = "#joy__bushi-get"
    else 
      x = "#joy__bushi-give::"..target.id
    end
    if player.room:askForSkillInvoke(player, self.name, data,x) then
      return true
    end
    self.cancel_cost = true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if #player:getPile("joy__zhanglu_mi") == 1 then
      room:obtainCard(target, player:getPile("joy__zhanglu_mi")[1], true, fk.ReasonPrey)
    else
      room:fillAG(player, player:getPile("joy__zhanglu_mi"))
      local id = room:askForAG(player, player:getPile("joy__zhanglu_mi"), false, self.name)
      room:closeAG(player)
      room:obtainCard(target, id, true, fk.ReasonPrey)
    end
  end,
}
local midao = fk.CreateTriggerSkill{
  name = "joy__midao",
  anim_type = "control",
  expand_pile = "joy__zhanglu_mi",
  events = {fk.AskForRetrial},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and #player:getPile("joy__zhanglu_mi") > 0
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local card = room:askForCard(player, 1, 1, false, self.name, true, ".|.|.|joy__zhanglu_mi|.|.", "#joy__midao-choose::" .. target.id, "joy__zhanglu_mi")
    if #card > 0 then
      self.cost_data = card[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    player.room:retrial(Fk:getCardById(self.cost_data), player, data, self.name)
    if not player.dead then
      player:drawCards(1,self.name)
    end
  end,
}
zhanglu:addSkill(yishe)
zhanglu:addSkill(bushi)
zhanglu:addSkill(midao)
Fk:loadTranslationTable{
  ["joy__zhanglu"] = "张鲁",
  ["#joy__zhanglu"] = "政宽教惠",
  ["joy__yishe"] = "义舍",
  [":joy__yishe"] = "结束阶段开始时，你可以摸两张牌，然后将两张牌置于武将牌上，称为“米”。当“米”移至其他区域后，"..
  "若你的武将牌上没有“米”，你回复1点体力。",
  ["joy__bushi"] = "布施",
  [":joy__bushi"] = "当你受到1点伤害后，若你拥有技能“义舍”，你可获得一张“米”；当你对其他角色造成1点伤害后，你可以交给其一张“米”。",
  ["joy__midao"] = "米道",
  [":joy__midao"] = "当一张判定牌生效前，你可以打出一张“米”代替之,然后你摸一张牌",
  ["joy__zhanglu_mi"] = "米",
  ["#joy__yishe-invoke"] = "义舍：你可以摸两张牌，然后将两张牌置为“米”",
  ["#joy__yishe-cost"] = "义舍：将两张牌置为“米”",
  ["#joy__bushi-get"] = "布施：是否获取一张“米”",
  ["#joy__bushi-give"] = "布施：是否交给 %dest 一张“米”",
  ["#joy__midao-choose"] = "米道：你可以打出一张“米”修改 %dest 的判定，然后摸一张牌",

  ["$joy__yishe1"] = " ",
  ["$joy__yishe2"] = " ",
  ["$joy__bushi1"] = " ",
  ["$joy__bushi2"] = " ",
  ["$joy__midao1"] = " ",
  ["$joy__midao2"] = " ",
  ["~zhanglu"] = " ",
}


local zhouxuan = General(extension, "joy__zhouxuan", "wei", 3)
local wumei = fk.CreateTriggerSkill{
  name = "joy__wumei",
  anim_type = "support",
  events = {fk.BeforeTurnStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryRound) == 0
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local to = room:askForChoosePlayers(player, table.map(table.filter(room.alive_players, function (p)
      return p:getMark("@@joy__wumei_extra") == 0 end), Util.IdMapper), 1, 1, "#joy__wumei-choose", self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    room:addPlayerMark(to, "@@joy__wumei_extra", 1)
    local hp_record = {}
    for _, p in ipairs(room.alive_players) do
      table.insert(hp_record, {p.id, p.hp})
    end
    room:setPlayerMark(to, "joy__wumei_record", hp_record)
    to:gainAnExtraTurn()
  end,

  refresh_events = {fk.AfterTurnEnd},
  can_refresh = function(self, event, target, player, data)
    return target == player and player:getMark("@@joy__wumei_extra") > 0
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, "@@joy__wumei_extra", 0)
    room:setPlayerMark(player, "joy__wumei_record", 0)
  end,
}
local wumei_delay = fk.CreateTriggerSkill{
  name = "#joy__wumei_delay",
  events = {fk.EventPhaseStart},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    return player == target and player.phase == Player.Finish and player:getMark("@@joy__wumei_extra") > 0
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:notifySkillInvoked(player, wumei.name, "special")
    local hp_record = player:getMark("joy__wumei_record")
    if type(hp_record) ~= "table" then return false end
    for _, p in ipairs(room:getAlivePlayers()) do
      local p_record = table.find(hp_record, function (sub_record)
        return #sub_record == 2 and sub_record[1] == p.id
      end)
      if p_record then
        p.hp = math.min(p.maxHp, p_record[2])
        room:broadcastProperty(p, "hp")
      end
    end
  end,
}
local zhanmeng = fk.CreateTriggerSkill{
  name = "joy__zhanmeng",
  events = {fk.CardUsing},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      local room = player.room
      local mark = player:getMark("joy__zhanmeng_last-turn")
      if type(mark) ~= "table" then
        mark = {}
        local logic = room.logic
        local current_event = logic:getCurrentEvent()
        local all_turn_events = logic.event_recorder[GameEvent.Turn]
        if type(all_turn_events) == "table" then
          local index = #all_turn_events
          if index > 0 then
            local turn_event = current_event:findParent(GameEvent.Turn)
            if turn_event ~= nil then
              index = index - 1
            end
            if index > 0 then
              current_event = all_turn_events[index]
              current_event:searchEvents(GameEvent.UseCard, 1, function (e)
                table.insertIfNeed(mark, e.data[1].card.trueName)
                return false
              end)
            end
          end
        end
        room:setPlayerMark(player, "joy__zhanmeng_last-turn", mark)
      end
      return (player:getMark("joy__zhanmeng1-turn") == 0 and not table.contains(mark, data.card.trueName)) or
        player:getMark("joy__zhanmeng2-turn") == 0 or (player:getMark("joy__zhanmeng3-turn") == 0 and
        not table.every(room.alive_players, function (p)
          return p == player or p:isNude()
        end))
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getMark("joy__zhanmeng_last-turn")
    local choices = {}
    self.cost_data = {}
    if player:getMark("joy__zhanmeng1-turn") == 0 and not table.contains(mark, data.card.trueName) then
      table.insert(choices, "joy__zhanmeng1")
    end
    if player:getMark("joy__zhanmeng2-turn") == 0 then
      table.insert(choices, "joy__zhanmeng2")
    end
    local targets = {}
    if player:getMark("joy__zhanmeng3-turn") == 0 then
      for _, p in ipairs(room.alive_players) do
        if p ~= player and not p:isNude() then
          table.insertIfNeed(choices, "joy__zhanmeng3")
          table.insert(targets, p.id)
        end
      end
    end
    table.insert(choices, "Cancel")
    local choice = room:askForChoice(player, choices, self.name, "#joy__zhanmeng-choice", false,
    {"joy__zhanmeng1", "joy__zhanmeng2", "joy__zhanmeng3", "Cancel"})
    if choice == "Cancel" then return false end
    self.cost_data[1] = choice
    if choice == "joy__zhanmeng3" then
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#joy__zhanmeng-choose", self.name, true)
      if #to > 0 then
        self.cost_data[2] = to[1]
      else
        return false
      end
    end
    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local choice = self.cost_data[1]
    room:setPlayerMark(player, choice.."-turn", 1)
    if choice == "joy__zhanmeng1" then
      local cards = {}
      for _, id in ipairs(room.draw_pile) do
        if not Fk:getCardById(id).is_damage_card then
          table.insertIfNeed(cards, id)
        end
      end
      if #cards > 0 then
        local card = table.random(cards)
        room:moveCards({
          ids = {card},
          to = player.id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonJustMove,
          proposer = player.id,
          skillName = self.name,
        })
      end
    elseif choice == "joy__zhanmeng2" then
      room:setPlayerMark(player, "joy__zhanmeng_delay-turn", data.card.trueName)
    elseif choice == "joy__zhanmeng3" then
      local p = room:getPlayerById(self.cost_data[2])
      local cards = room:askForDiscard(p, 2, 2, true, self.name, false, ".", "#joy__zhanmeng-discard:"..player.id)
      local x = Fk:getCardById(cards[1]).number
      if #cards == 2 then
        x = x + Fk:getCardById(cards[2]).number
      end
      if x > 10 and not p.dead then
        room:damage{
          from = player,
          to = p,
          damage = 1,
          damageType = fk.FireDamage,
          skillName = self.name,
        }
      end
    end
  end,

  refresh_events = {fk.AfterTurnEnd},
  can_refresh = Util.TrueFunc,
  on_refresh = function(self, event, target, player, data)
    player.room:setPlayerMark(player, "@joy__zhanmeng_delay", player:getMark("joy__zhanmeng_delay-turn"))
  end,
}
local zhanmeng_delay = fk.CreateTriggerSkill{
  name = "#joy__zhanmeng_delay",
  anim_type = "drawcard",
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    return player:usedSkillTimes(self.name) == 0 and player:getMark("@joy__zhanmeng_delay") == data.card.trueName
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = {}
    for _, id in ipairs(room.draw_pile) do
      if Fk:getCardById(id).is_damage_card then
        table.insertIfNeed(cards, id)
      end
    end
    if #cards > 0 then
      local card = table.random(cards)
      room:moveCards({
        ids = {card},
        to = player.id,
        toArea = Card.PlayerHand,
        moveReason = fk.ReasonJustMove,
        proposer = player.id,
        skillName = self.name,
      })
    end
  end,
}
wumei:addRelatedSkill(wumei_delay)
zhanmeng:addRelatedSkill(zhanmeng_delay)
zhouxuan:addSkill(wumei)
zhouxuan:addSkill(zhanmeng)
Fk:loadTranslationTable{
  ["joy__zhouxuan"] = "周宣",
  ["#joy__zhouxuan"] = "夜华青乌",

  ["joy__wumei"] = "寤寐",
  [":joy__wumei"] = "每轮限一次，回合开始前，你可以令一名角色执行一个额外的回合：该回合结束时，将所有存活角色的体力值调整为此额外回合开始时的数值。",
  ["joy__zhanmeng"] = "占梦",
  [":joy__zhanmeng"] = "你使用牌时，可以执行以下一项（每回合每项各限一次）：<br>"..
  "1.上一回合内，若没有同名牌被使用，你获得一张非伤害牌。<br>"..
  "2.下一回合内，当同名牌首次被使用后，你获得一张伤害牌。<br>"..
  "3.令一名其他角色弃置两张牌，若点数之和大于10，对其造成1点火焰伤害。",
  ["#joy__wumei-choose"] = "寤寐: 你可以令一名角色执行一个额外的回合",
  ["#joy__wumei_delay"] = "寤寐",
  ["@@joy__wumei_extra"] = "寤寐",
  ["joy__zhanmeng1"] = "你获得一张非伤害牌",
  ["joy__zhanmeng2"] = "下一回合内，当同名牌首次被使用后，你获得一张伤害牌",
  ["joy__zhanmeng3"] = "令一名其他角色弃置两张牌，若点数之和大于10，对其造成1点火焰伤害",
  ["#joy__zhanmeng_delay"] = "占梦",
  ["@joy__zhanmeng_delay"] = "占梦",
  ["#joy__zhanmeng-choice"] = "是否发动 占梦，选择一项效果",
  ["#joy__zhanmeng-choose"] = "占梦: 令一名其他角色弃置两张牌，若点数之和大于10，对其造成1点火焰伤害",
  ["#joy__zhanmeng-discard"] = "占梦：弃置2张牌，若点数之和大于10，%src 对你造成1点火焰伤害",

  ["$joy__wumei1"] = "大梦若期，皆付一枕黄粱。",
  ["$joy__wumei2"] = "日所思之，故夜所梦之。",
  ["$joy__zhanmeng1"] = "梦境缥缈，然有迹可占。",
  ["$joy__zhanmeng2"] = "万物有兆，唯梦可卜。",
  ["~joy__zhouxuan"] = "人生如梦，假时亦真。",
}

local pangdegong = General(extension, "joy__pangdegong", "qun", 3)
local heqia = fk.CreateActiveSkill{
  name = "joy__heqia",
  min_card_num = 0,
  target_num = 1,
  prompt = "#joy__heqia-invoke",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  interaction = function()
    local choices = {}
    if not Self:isNude() then table.insert(choices, "heqia_give") end
    if table.find(Fk:currentRoom().alive_players, function(p) return Self ~= p and not p:isNude() end) then
      table.insert(choices, "heqia_prey")
    end
    return UI.ComboBox {choices = choices}
  end,
  card_filter = function(self, to_select, selected)
    if not self.interaction.data or self.interaction.data == "heqia_prey" then return false end
    return true
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    if not self.interaction.data or #selected > 0 or to_select == Self.id then return false end
    if self.interaction.data == "heqia_give" then
      return #selected_cards > 0
    else
      return not Fk:currentRoom():getPlayerById(to_select):isNude()
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local toid = effect.tos
    local cards = effect.cards
    local dummy = Fk:cloneCard("dilu")
    local to = player
    if #cards > 0 then
      to = room:getPlayerById(toid[1])
      dummy:addSubcards(cards)
    else
      local src = room:getPlayerById(toid[1])
      local cards = room:askForCard(src, 1, 999, true, self.name, false, ".", "#heqia-give:"..player.id)
      dummy:addSubcards(cards)
    end
    room:moveCardTo(dummy, Card.PlayerHand, to, fk.ReasonGive, self.name, nil, false, player.id)
    if to.dead or to:isKongcheng() then return end
    room:setPlayerMark(to, "heqia-tmp", #dummy.subcards)
    local success, dat = room:askForUseActiveSkill(to, "joy__heqia_viewas", "#heqia-use:::"..#dummy.subcards, true)
    if success and dat then
      local card = Fk:cloneCard(dat.interaction)
      card:addSubcards(dat.cards)
      room:useCard{
        from = to.id,
        tos = table.map(dat.targets, function(id) return {id} end),
        card = card,
        extraUse = true,
      }
    end
  end,

}
local heqia_viewas = fk.CreateActiveSkill{
  name = "joy__heqia_viewas",
  interaction = function()
    local names = {}
    for _, id in ipairs(Fk:getAllCardIds()) do
      local card = Fk:getCardById(id)
      if card.type == Card.TypeBasic and not card.is_derived and Self:canUse(card) and not Self:prohibitUse(card) then
        table.insertIfNeed(names, card.name)
      end
    end
    if #names == 0 then return end
    return UI.ComboBox {choices = names}
  end,
  card_filter = function (self, to_select, selected)
    return #selected == 0 and Fk:currentRoom():getCardArea(to_select) ~= Card.PlayerEquip
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    if not self.interaction.data or #selected_cards ~= 1 then return false end
    if #selected >= Self:getMark("heqia-tmp") then return false end
    local to_use = Fk:cloneCard(self.interaction.data)
    to_use.skillName = "heqia"
    if Self:isProhibited(Fk:currentRoom():getPlayerById(to_select), to_use) then return false end
    return to_use.skill:modTargetFilter(to_select, selected, Self.id, to_use, false)
  end,
  feasible = function(self, selected, selected_cards)
    if not self.interaction.data or #selected_cards ~= 1 then return false end
    local to_use = Fk:cloneCard(self.interaction.data)
    to_use.skillName = "heqia"
    if to_use.skill:getMinTargetNum() == 0 then
      return (#selected == 0 or table.contains(selected, Self.id)) and to_use.skill:feasible(selected, selected_cards, Self, to_use)
    else
      return #selected > 0
    end
  end,
}
local yinyi = fk.CreateTriggerSkill{
  name = "joy__yinyi",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.DamageInflicted},
  can_trigger = function(self, _, target, player, data)
    return target == player and player:hasSkill(self) and data.damageType == fk.NormalDamage and
      data.from and data.from:getHandcardNum() ~= player:getHandcardNum() and data.from.hp ~= player.hp and
      player:usedSkillTimes(self.name, Player.HistoryTurn) == 0
  end,
  on_use = Util.TrueFunc,
}
Fk:addSkill(heqia_viewas)
pangdegong:addSkill(heqia)
pangdegong:addSkill(yinyi)
Fk:loadTranslationTable{
  ["joy__pangdegong"] = "庞德公",
  ["#joy__pangdegong"] = "友睦风疏",

  ["joy__heqia"] = "和洽",
  [":joy__heqia"] = "出牌阶段限一次，你可以选择一项：1.你交给一名其他角色至少一张牌；2.令一名有手牌的其他角色交给你至少一张牌。然后获得牌的角色可以将一张手牌当任意基本牌使用（无距离次数限制），且此牌目标上限改为X（X为其本次获得的牌数）。",
  ["joy__yinyi"] = "隐逸",
  [":joy__yinyi"] = "锁定技，每回合限一次，当你受到非属性伤害时，若伤害来源的手牌数与体力值均与你不同，防止此伤害。",
  ["#joy__heqia-invoke"] = "和洽：交给一名其他角色至少一张牌，或选择一名角色将至少一张牌交给你",
  ["joy__heqia_viewas"] = "和洽",
}

local ruanyu = General(extension, "joy__ruanyu", "wei", 3)
local xingzuo = fk.CreateTriggerSkill{
  name = "joy__xingzuo",
  anim_type = "control",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Play
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = room:getNCards(3, "bottom")
    cards = table.reverse(cards)
    --FIXME:从牌堆底获取牌是逆序的……
    local handcards = player:getCardIds(Player.Hand)
    local cardmap = room:askForArrangeCards(player, self.name,
    {cards, handcards, "Bottom", "$Hand"}, "#xingzuo-invoke")
    U.swapCardsWithPile(player, cardmap[1], cardmap[2], self.name, "Bottom")
  end,
}
local xingzuo_delay = fk.CreateTriggerSkill{
  name = "#joy__xingzuo_delay",
  anim_type = "control",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and not player.dead and player.phase == Player.Finish and
    player:usedSkillTimes(xingzuo.name, Player.HistoryTurn) > 0
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = table.map(table.filter(room.alive_players, function(p)
      return not p:isKongcheng() end), Util.IdMapper)
    local to = room:askForChoosePlayers(player, targets, 1, 1, "#joy__xingzuo-choose", xingzuo.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(xingzuo.name)
    local to = room:getPlayerById(self.cost_data)
    local cards = to:getCardIds(Player.Hand)
    local n = #cards
    room:moveCards({
      from = to.id,
      ids = cards,
      toArea = Card.Processing,
      moveReason = fk.ReasonExchange,
      proposer = player.id,
      skillName = xingzuo.name,
      moveVisible = false,
    })
    if not to.dead then
      room:moveCardTo(room:getNCards(3, "bottom"), Card.PlayerHand, to, fk.ReasonExchange, xingzuo.name, nil, false, player.id)
    end
    cards = table.filter(cards, function (id)
      return room:getCardArea(id) == Card.Processing
    end)
    if #cards > 0 then
      cards = table.random(cards, #cards)
      room:moveCards({
        ids = cards,
        fromArea = Card.Processing,
        toArea = Card.DrawPile,
        moveReason = fk.ReasonExchange,
        skillName = xingzuo.name,
        moveVisible = false,
        drawPilePosition = -1,
      })
    end
  end,
}

local miaoxian = fk.CreateViewAsSkill{
  name = "joy__miaoxian",
  pattern = ".|.|.|.|.|trick|.",
  prompt = "#miaoxian",
  interaction = function()
    local blackcards = table.filter(Self.player_cards[Player.Hand], function(id) return Fk:getCardById(id).color == Card.Black end)
    if #blackcards ~= 1 then return false end
    local names, all_names = {} , {}
    for _, id in ipairs(Fk:getAllCardIds()) do
      local card = Fk:getCardById(id)
      if card:isCommonTrick() and not card.is_derived and not table.contains(all_names, card.name) then
        table.insert(all_names, card.name)
        local to_use = Fk:cloneCard(card.name)
        to_use:addSubcard(blackcards[1])
        if ((Fk.currentResponsePattern == nil and card.skill:canUse(Self, to_use) and not Self:prohibitUse(to_use)) or
        (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(to_use))) then
          table.insert(names, card.name)
        end
      end
    end
    if #names == 0 then return false end
    return UI.ComboBox { choices = names, all_choices = all_names }
  end,
  card_filter = Util.FalseFunc,
  view_as = function(self, cards)
    if not self.interaction.data then return nil end
    local blackcards = table.filter(Self.player_cards[Player.Hand], function(id) return Fk:getCardById(id).color == Card.Black end)
    if #blackcards ~= 1 then return nil end
    local card = Fk:cloneCard(self.interaction.data)
    card:addSubcard(blackcards[1])
    card.skillName = self.name
    return card
  end,
  enabled_at_play = function(self, player)
    return not player:isKongcheng() and
      player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 and
      #table.filter(player:getCardIds("h"), function(id) return Fk:getCardById(id).color == Card.Black end) == 1
  end,
  enabled_at_response = function(self, player, response)
    return not response and Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):matchExp(self.pattern) and
      not player:isKongcheng() and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 and
      #table.filter(player:getCardIds("h"), function(id) return Fk:getCardById(id).color == Card.Black end) == 1
  end,
}
local miaoxian_trigger = fk.CreateTriggerSkill{
  name = "#joy__miaoxian_trigger",
  anim_type = "drawcard",
  events = {fk.CardUsing},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and table.every(player:getCardIds("h"), function(id)
      return Fk:getCardById(id).color ~= Card.Red end) and data.card.color == Card.Red and
      not (data.card:isVirtual() and #data.card.subcards ~= 1)
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    player.room:notifySkillInvoked(player, miaoxian.name, self.anim_type)
    player:broadcastSkillInvoke(miaoxian.name)
    player:drawCards(1, "miaoxian")
  end,
}
xingzuo:addRelatedSkill(xingzuo_delay)
miaoxian:addRelatedSkill(miaoxian_trigger)
ruanyu:addSkill(xingzuo)
ruanyu:addSkill(miaoxian)
Fk:loadTranslationTable{
  ["joy__ruanyu"] = "阮瑀",
  
  ["joy__xingzuo"] = "兴作",
  [":joy__xingzuo"] = "出牌阶段开始时，你可观看牌堆底的三张牌并用任意张手牌替换其中等量的牌。若如此做，结束阶段，"..
  "你可以令一名有手牌的角色用所有手牌替换牌堆底的三张牌。",
  ["#joy__xingzuo_delay"] = "兴作",
  ["joy__miaoxian"] = "妙弦",
  ["#joy__miaoxian_trigger"] = "妙弦",
  [":joy__miaoxian"] = "每回合限一次，你可以将手牌中的唯一黑色牌当任意一张普通锦囊牌使用；当你使用手牌中的唯一红色牌时，你摸一张牌。",
  ["#joy__xingzuo-choose"] = "兴作：你可以令一名角色用所有手牌替换牌堆底的三张牌。",

}


local licaiwei = General(extension, "joy__licaiwei", "qun", 3, 3, General.Female)
local qibie = fk.CreateTriggerSkill{
  name = "joy__qibie",
  anim_type = "drawcard",
  events = {fk.Deathed},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and not player:isKongcheng()
  end,
  on_cost = function(self, event, target, player, data)
    local cards = player.room:askForDiscard(player,1,player:getHandcardNum(),false,self.name,false,".","泣别：你可以弃置任意张手牌，然后回复一点体力并摸弃置牌数+1张牌",true)
    if #cards > 0 then
      self.cost_data = cards
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local n = #self.cost_data
    player.room:moveCardTo(self.cost_data, Card.DiscardPile, player, fk.ReasonDiscard, self.name)
    if player.dead then return end
    if player:isWounded() then
      player.room:recover({
        who = player,
        num = 1,
        recoverBy = player,
        skillName = self.name
      })
    end
    if player.dead then return end
    player:drawCards(n + 1, self.name)
  end,
}
licaiwei:addSkill("yijiao")
licaiwei:addSkill(qibie)
Fk:loadTranslationTable{
  ["joy__licaiwei"] = "李采薇",
  ["#joy__licaiwei"] = "啼雨孤鸯",
  
  ["joy__qibie"] = "泣别",
  [":joy__qibie"] = "一名角色死亡后，你可以弃置任意张手牌，然后回复1点体力值并摸弃置牌数+1张牌。",

}

local jiangwanfeiyi = General(extension, "joy__jiangwanfeiyi", "shu", 3)
jiangwanfeiyi:addSkill("ld__shengxi")
local shoucheng = fk.CreateTriggerSkill{
  name = "joy__shoucheng",
  anim_type = "support",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) or player:usedSkillTimes(self.name, Player.HistoryTurn) > 0 then return end
    for _, move in ipairs(data) do
      if move.from then
        local from = player.room:getPlayerById(move.from)
        if from:getHandcardNum() < from.hp and from.phase == Player.NotActive and not from.dead then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
              return true
            end
          end
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local targets = {}
    local room = player.room
    for _, move in ipairs(data) do
      if move.from then
        local from = room:getPlayerById(move.from)
        if from:getHandcardNum() < from.hp and from.phase == Player.NotActive and not from.dead then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
              table.insertIfNeed(targets, from.id)
              break
            end
          end
        end
      end
    end
    if #targets == 0 then return end
    if #targets > 1 then
      local tos = player.room:askForChoosePlayers(player, targets, 1, 1, "#joy__shoucheng-choose", self.name, true)
      if #tos > 0 then
        self.cost_data = tos[1]
        return true
      end
    else
      self.cost_data = targets[1]
      return player.room:askForSkillInvoke(player, self.name, nil, "#joy__shoucheng-draw::" .. targets[1])
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    room:doIndicate(player.id, {to.id})
    player:broadcastSkillInvoke("shoucheng")
    to:drawCards(2, self.name)
  end,
}
jiangwanfeiyi:addSkill(shoucheng)
Fk:loadTranslationTable{
  ["joy__jiangwanfeiyi"] = "蒋琬费祎",
  ["#joy__jiangwanfeiyi"] = "社稷股肱",

  ["joy__shoucheng"] = "守成",
  [":joy__shoucheng"] = "每回合限一次，当一名角色于其回合外失去牌后，若其手牌数小于体力值，你可令其摸两张牌。",

  ["#joy__shoucheng-draw"] = "守成：你可令 %dest 摸两张牌",
  ["#joy__shoucheng-choose"] = "守成：你可令一名手牌数小于体力值的角色摸两张牌",
}

local tengfanglan = General(extension, "joy__tengfanglan", "wu", 3, 3, General.Female)
tengfanglan:addSkill("ty__luochong")
tengfanglan:addSkill("ty__aichen")
Fk:loadTranslationTable{
  ["joy__tengfanglan"] = "滕芳兰",
  ["#joy__tengfanglan"] = "铃兰零落",
}

local huangzu = General(extension, "joy__huangzu", "qun", 4)
local xiaojun = fk.CreateTriggerSkill{
  name = "joy__xiaojun",
  events = {fk.TargetSpecified},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and data.to ~= player.id then
      local to = player.room:getPlayerById(data.to)
      return not to.dead and to:getHandcardNum() >= 1 and U.isOnlyTarget(to, data, event)
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(data.to)
    local n = to:getHandcardNum()
    local m = n//2
    if n%2 > 0 then
      m = m + 1
    end
    self.cost_data = m
    return player.room:askForSkillInvoke(player, self.name, nil,
      "#xiaojun-invoke::"..data.to..":"..tostring(m)..":"..data.card:getSuitString())
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(data.to)
    local n = self.cost_data
    local cards = room:askForCardsChosen(player, to, n, n, "h", self.name)
    room:throwCard(cards, self.name, to, player)
    if not player:isKongcheng() and data.card ~= Card.NoSuit and table.find(cards, function(id)
        return Fk:getCardById(id).suit == data.card.suit end) then
      room:askForDiscard(player, 1, 1, false, self.name, false)
    end
  end,
}
huangzu:addSkill("jinggong")
huangzu:addSkill(xiaojun)
Fk:loadTranslationTable{
  ["joy__huangzu"] = "黄祖",
  ["#joy__huangzu"] = "引江为弣",
  
  ["joy__xiaojun"] = "骁隽",
  [":joy__xiaojun"] = "你使用牌指定其他角色为唯一目标后，你可以弃置其一半手牌（向上取整）。"..
  "若其中有与你指定其为目标的牌花色相同的牌，你弃置一张手牌。",

}

local dingfuren = General(extension, "joy__dingfuren", "wei", 3, 3, General.Female)
dingfuren:addSkill("fengyan")
dingfuren:addSkill("fudao")
Fk:loadTranslationTable{
  ["joy__dingfuren"] = "丁尚涴",
  ["#joy__dingfuren"] = "与君不载",
}

local liuba = General(extension, "joy__liuba", "shu", 3)
liuba:addSkill("ty__zhubi")
liuba:addSkill("liuzhuan")
Fk:loadTranslationTable{
  ["joy__liuba"] = "刘巴",
  ["#joy__liuba"] = "清尚之节",
}

local yanghu = General(extension, "joy__yanghu", "wei", 3)
local deshao = fk.CreateTriggerSkill{
  name = "joy__deshao",
  anim_type = "defensive",
  events = {fk.TargetConfirmed},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card.color == Card.Black  and player:usedSkillTimes(self.name, Player.HistoryTurn) < 2
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#joy__deshao-invoke::"..data.from)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:drawCards(1, self.name)
    local from = room:getPlayerById(data.from)
    if from:getHandcardNum() >= player:getHandcardNum() and  room:askForSkillInvoke(player,self.name,nil,"明伐：你可以弃置 %dest 一张牌::"..data.from) then
      local id = room:askForCardChosen(player, from, "he", self.name)
      room:throwCard(id, self.name, from, player)
    end
  end,
}
yanghu:addSkill(deshao)
yanghu:addSkill("mingfa")
Fk:loadTranslationTable{
  ["joy__yanghu"] = "羊祜",
  ["#joy__yanghu"] = "制纮同轨",
  
  ["joy__deshao"] = "德劭",
  [":joy__deshao"] = "每回合限两次，当你成为任意角色使用黑色牌的目标后，你可以摸一张牌，然后若其手牌数大于等于你，你可以弃置其一张牌。",
  ["#joy__deshao-invoke"] = "德劭：你可以摸一张牌，然后若 %dest 手牌数不少于你，你可弃置其一张牌",
}

local jiangqin = General(extension, "joy__jiangqin", "wu", 4)
local jianyi = fk.CreateTriggerSkill{
  name = "joy__jianyi",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    if target ~= player and player:hasSkill(self) then
      local ids = {}
      local events =  player.room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function(e)
        for _, move in ipairs(e.data) do
          if move.moveReason == fk.ReasonDiscard then
            for _, info in ipairs(move.moveInfo) do
              if (Fk:getCardById(info.cardId).sub_type == Card.SubtypeArmor or Fk:getCardById(info.cardId).sub_type == Card.SubtypeWeapon)
              and player.room:getCardArea(info.cardId) == Card.DiscardPile then
                table.insertIfNeed(ids, info.cardId)
              end
            end
          end
        end
      end, Player.HistoryTurn)
      if #ids > 0 then
        self.cost_data = ids
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local get = room:askForCardChosen(player, player, {card_data = {{self.name, self.cost_data}}}, self.name)
    room:moveCards({
      ids = {get},
      to = player.id,
      toArea = Card.PlayerHand,
      moveReason = fk.ReasonPrey,
      proposer = player.id,
      skillName = self.name,
    })
  end,
}
local shangyi = fk.CreateActiveSkill{
  name = "joy__shangyi",
  anim_type = "control",
  card_num = 1,
  target_num = 1,
  prompt = "#joy__shangyi",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and not player:isKongcheng()
  end,
  card_filter = function(self, to_select, selected)
    if #selected == 0 and not Self:prohibitDiscard(Fk:getCardById(to_select)) then
      if Fk:currentRoom():getCardArea(to_select) == Player.Hand then
        return Self:getHandcardNum() > 1
      else
        return true
      end
    end
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    return #selected == 0 and to_select ~= Self.id and not Fk:currentRoom():getPlayerById(to_select):isKongcheng()
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:throwCard(effect.cards, self.name, player, player)
    if player.dead or target.dead or player:isKongcheng() or target:isKongcheng() then return end
    U.viewCards(target, player:getCardIds("h"), self.name)
    local id = room:askForCardChosen(player, target, { card_data = { { "$Hand", target:getCardIds(Player.Hand) }  } }, self.name,"尚义：选择其中一张牌，你获得之或与自己的一张手牌交换")
    local choice1 = "获得此牌，若此牌为黑你摸一张牌"
    local choice2 = "交换此牌，若此牌为红你摸一张牌"
    local choices = {choice1}
    if not player:isKongcheng() then
      table.insertIfNeed(choices,choice2)
    end
    local choice = room:askForChoice(player,choices,self.name,"尚义：选择一项执行",false,{choice1,choice2})
    if choice == choice1 then
      room:obtainCard(player, id, false, fk.ReasonPrey)
      if Fk:getCardById(id).color == Card.Black and not player.dead then
        player:drawCards(1,self.name)
      end
    elseif choice == choice2 then
      target:showCards({id})
      local card = room:askForCard(player,1,1,false,self.name,false,".","选择一张手牌与 "..Fk:translate(target.general).." 的牌交换。")
      if #card > 0 then
        local move1 = {
          from = player.id,
          ids = {card[1]},
          to = target.id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonJustMove,
          proposer = player.id,
          skillName = self.name,
        }
        local move2 = {
          from = target.id,
          ids ={id},
          to = player.id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonJustMove,
          proposer = player.id,
          skillName = self.name,
        }
        room:moveCards(move1, move2)
        if not player.dead and Fk:getCardById(id).color == Card.Red then
          player:drawCards(1,self.name)
        end
      end
    end
  end,
}
jiangqin:addSkill(jianyi)
jiangqin:addSkill(shangyi)
Fk:loadTranslationTable{
  ["joy__jiangqin"] = "蒋钦",
  ["#joy__jiangqin"] = "折节尚义",
  ["joy__jianyi"] = "俭衣",
  [":joy__jianyi"] = "锁定技，其他角色回合结束时，若弃牌堆中有本回合弃置的防具牌或武器牌，则你选择其中一张获得。",
  ["joy__shangyi"] = "尚义",
  [":joy__shangyi"] = "出牌阶段限一次，你可以弃置一张牌并令一名有手牌的其他角色观看你的手牌，然后你观看其手牌并选择一项：<br>①获得其中一张牌，若为黑你摸一张牌；<br>②选择其中一张牌与自己的一张手牌交换，若你交换获得的牌为红则你摸一张牌。",
  ["#joy__shangyi"] = "尚义：弃置一张牌令一名角色观看你的手牌，然后你观看其手牌并选择获得或交换其中一张牌",

}

local shamoke = General(extension, "joy__shamoke", "shu", 4)
local jilis = fk.CreateTriggerSkill{
  name = "joy__jilis",
  anim_type = "drawcard",
  events = {fk.CardUsing, fk.CardResponding,fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    if event == fk.TurnEnd then
      return target == player and player:hasSkill(self) and not player:isNude()
    else
    if target == player and player:hasSkill(self) then
      local x, y = player:getAttackRange(), player:getMark("joy__jilis_times-turn")
      if x >= y then
        local room = player.room
        local logic = room.logic
        local end_id = player:getMark("joy__jilis_record-turn")
        local e = logic:getCurrentEvent()
        if end_id == 0 then
          local turn_event = e:findParent(GameEvent.Turn, false)
          if turn_event == nil then return false end
          end_id = turn_event.id
        end
        room:setPlayerMark(player, "joy__jilis_record-turn", logic.current_event_id)
        local events = logic.event_recorder[GameEvent.UseCard] or Util.DummyTable
        for i = #events, 1, -1 do
          e = events[i]
          if e.id <= end_id then break end
          local use = e.data[1]
          if use.from == player.id then
            y = y + 1
          end
        end
        events = logic.event_recorder[GameEvent.RespondCard] or Util.DummyTable
        for i = #events, 1, -1 do
          e = events[i]
          if e.id <= end_id then break end
          local use = e.data[1]
          if use.from == player.id then
            y = y + 1
          end
        end
        room:setPlayerMark(player, "joy__jilis_times-turn", y)
        return x == y
      end
    end
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.TurnEnd then
      local cards = player.room:askForDiscard(player,1,1,true,self.name,true,".","蒺藜：你可以弃置一张牌然后摸一张牌。",true)
      if #cards > 0 then
        self.cost_data = cards[1]
        return true
      end
    else
      return player.room:askForSkillInvoke(player,self.name,nil,"是否发动〖蒺藜〗摸 "..player:getAttackRange().." 张牌？")
    end
  end,
  on_use = function(self, event, target, player, data)
    if event == fk.TurnEnd then
      player.room:throwCard(self.cost_data,self.name,player,player)
      if not player.dead then
        player:drawCards(1,self.name)
      end
    else
      player:drawCards(player:getAttackRange())
    end
  end,
}
shamoke:addSkill(jilis)
Fk:loadTranslationTable{
  ["joy__shamoke"] = "沙摩柯",
  ["#joy__shamoke"] = "五溪蛮夷",
  ["joy__jilis"] = "蒺藜",
  [":joy__jilis"] = "当你于一回合内使用或打出第X张牌时，你可以摸X张牌（X为你的攻击范围）。<br>你的回合结束时，你可以弃置一张牌并摸一张牌。",

}

return extension
